X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fstate_tracker%2Fst_manager.c;h=617a691a67c33871a0c84d90feb9bc3d2986f2af;hb=bbfad34606b8fc91c3671bb9a6e6545d669e6f81;hp=dd9597be766182e28bf81e2091fb69f27cb58ce0;hpb=c6cbde5008e27cccb06411146bc673835991ae91;p=mesa.git diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c index dd9597be766..617a691a67c 100644 --- a/src/mesa/state_tracker/st_manager.c +++ b/src/mesa/state_tracker/st_manager.c @@ -26,7 +26,10 @@ */ #include "main/mtypes.h" +#include "main/extensions.h" #include "main/context.h" +#include "main/debug_output.h" +#include "main/glthread.h" #include "main/texobj.h" #include "main/teximage.h" #include "main/texstate.h" @@ -35,9 +38,12 @@ #include "main/fbobject.h" #include "main/renderbuffer.h" #include "main/version.h" +#include "util/hash_table.h" #include "st_texture.h" #include "st_context.h" +#include "st_debug.h" +#include "st_extensions.h" #include "st_format.h" #include "st_cb_fbo.h" #include "st_cb_flush.h" @@ -52,26 +58,21 @@ #include "util/u_inlines.h" #include "util/u_atomic.h" #include "util/u_surface.h" +#include "util/list.h" -/** - * Cast wrapper to convert a struct gl_framebuffer to an st_framebuffer. - * Return NULL if the struct gl_framebuffer is a user-created framebuffer. - * We'll only return non-null for window system framebuffers. - * Note that this function may fail. - */ -static INLINE struct st_framebuffer * -st_ws_framebuffer(struct gl_framebuffer *fb) +struct hash_table; +struct st_manager_private { - /* FBO cannot be casted. See st_new_framebuffer */ - if (fb && _mesa_is_winsys_fbo(fb)) - return (struct st_framebuffer *) fb; - return NULL; -} + struct hash_table *stfbi_ht; /* framebuffer iface objects hash table */ + mtx_t st_mutex; +}; + +static void st_manager_destroy(struct st_manager *); /** * Map an attachment to a buffer index. */ -static INLINE gl_buffer_index +static inline gl_buffer_index attachment_to_buffer_index(enum st_attachment_type statt) { gl_buffer_index index; @@ -107,7 +108,7 @@ attachment_to_buffer_index(enum st_attachment_type statt) /** * Map a buffer index to an attachment. */ -static INLINE enum st_attachment_type +static inline enum st_attachment_type buffer_index_to_attachment(gl_buffer_index index) { enum st_attachment_type statt; @@ -149,7 +150,7 @@ st_context_validate(struct st_context *st, struct st_framebuffer *stread) { if (stdraw && stdraw->stamp != st->draw_stamp) { - st->dirty.st |= ST_NEW_FRAMEBUFFER; + st->dirty |= ST_NEW_FRAMEBUFFER; _mesa_resize_framebuffer(st->ctx, &stdraw->Base, stdraw->Base.Width, stdraw->Base.Height); @@ -158,7 +159,7 @@ st_context_validate(struct st_context *st, if (stread && stread->stamp != st->read_stamp) { if (stread != stdraw) { - st->dirty.st |= ST_NEW_FRAMEBUFFER; + st->dirty |= ST_NEW_FRAMEBUFFER; _mesa_resize_framebuffer(st->ctx, &stread->Base, stread->Base.Width, stread->Base.Height); @@ -185,10 +186,6 @@ st_framebuffer_validate(struct st_framebuffer *stfb, boolean changed = FALSE; int32_t new_stamp; - /* Check for incomplete framebuffers (e.g. EGL_KHR_surfaceless_context) */ - if (!stfb->iface) - return; - new_stamp = p_atomic_read(&stfb->iface->stamp); if (stfb->iface_stamp == new_stamp) return; @@ -196,8 +193,8 @@ st_framebuffer_validate(struct st_framebuffer *stfb, /* validate the fb */ do { if (!stfb->iface->validate(&st->iface, stfb->iface, stfb->statts, - stfb->num_statts, textures)) - return; + stfb->num_statts, textures)) + return; stfb->iface_stamp = new_stamp; new_stamp = p_atomic_read(&stfb->iface->stamp); @@ -230,7 +227,12 @@ st_framebuffer_validate(struct st_framebuffer *stfb, u_surface_default_template(&surf_tmpl, textures[i]); ps = st->pipe->create_surface(st->pipe, textures[i], &surf_tmpl); if (ps) { - pipe_surface_reference(&strb->surface, ps); + struct pipe_surface **psurf = + util_format_is_srgb(ps->format) ? &strb->surface_srgb : + &strb->surface_linear; + + pipe_surface_reference(psurf, ps); + strb->surface = *psurf; pipe_resource_reference(&strb->texture, ps->texture); /* ownership transfered */ pipe_surface_reference(&ps, NULL); @@ -279,7 +281,8 @@ st_framebuffer_update_attachments(struct st_framebuffer *stfb) } /** - * Add a renderbuffer to the framebuffer. + * Add a renderbuffer to the framebuffer. The framebuffer is one that + * corresponds to a window and is not a user-created FBO. */ static boolean st_framebuffer_add_renderbuffer(struct st_framebuffer *stfb, @@ -289,8 +292,7 @@ st_framebuffer_add_renderbuffer(struct st_framebuffer *stfb, enum pipe_format format; boolean sw; - if (!stfb->iface) - return FALSE; + assert(_mesa_is_winsys_fbo(&stfb->Base)); /* do not distinguish depth/stencil buffers */ if (idx == BUFFER_STENCIL) @@ -321,13 +323,21 @@ st_framebuffer_add_renderbuffer(struct st_framebuffer *stfb, return FALSE; if (idx != BUFFER_DEPTH) { - _mesa_add_renderbuffer(&stfb->Base, idx, rb); + _mesa_attach_and_own_rb(&stfb->Base, idx, rb); + return TRUE; } - else { - if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0)) - _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, rb); - if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)) - _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, rb); + + bool rb_ownership_taken = false; + if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0)) { + _mesa_attach_and_own_rb(&stfb->Base, BUFFER_DEPTH, rb); + rb_ownership_taken = true; + } + + if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)) { + if (rb_ownership_taken) + _mesa_attach_and_reference_rb(&stfb->Base, BUFFER_STENCIL, rb); + else + _mesa_attach_and_own_rb(&stfb->Base, BUFFER_STENCIL, rb); } return TRUE; @@ -366,6 +376,7 @@ st_visual_to_context_mode(const struct st_visual *visual, mode->rgbBits = mode->redBits + mode->greenBits + mode->blueBits + mode->alphaBits; + mode->sRGBCapable = util_format_is_srgb(visual->color_format); } if (visual->depth_stencil_format != PIPE_FORMAT_NONE) { @@ -450,13 +461,15 @@ st_framebuffer_create(struct st_context *st, st_pipe_format_to_mesa_format(srgb_format) != MESA_FORMAT_NONE && screen->is_format_supported(screen, srgb_format, PIPE_TEXTURE_2D, stfbi->visual->samples, - PIPE_BIND_RENDER_TARGET)) + (PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_RENDER_TARGET))) mode.sRGBCapable = GL_TRUE; } _mesa_initialize_window_framebuffer(&stfb->Base, &mode); stfb->iface = stfbi; + stfb->iface_ID = stfbi->ID; stfb->iface_stamp = p_atomic_read(&stfbi->stamp) - 1; /* add the color buffer */ @@ -478,7 +491,7 @@ st_framebuffer_create(struct st_context *st, /** * Reference a framebuffer. */ -static void +void st_framebuffer_reference(struct st_framebuffer **ptr, struct st_framebuffer *stfb) { @@ -486,6 +499,128 @@ st_framebuffer_reference(struct st_framebuffer **ptr, _mesa_reference_framebuffer((struct gl_framebuffer **) ptr, fb); } + +static uint32_t +st_framebuffer_iface_hash(const void *key) +{ + return (uintptr_t)key; +} + + +static bool +st_framebuffer_iface_equal(const void *a, const void *b) +{ + return (struct st_framebuffer_iface *)a == (struct st_framebuffer_iface *)b; +} + + +static boolean +st_framebuffer_iface_lookup(struct st_manager *smapi, + const struct st_framebuffer_iface *stfbi) +{ + struct st_manager_private *smPriv = + (struct st_manager_private *)smapi->st_manager_private; + struct hash_entry *entry; + + assert(smPriv); + assert(smPriv->stfbi_ht); + + mtx_lock(&smPriv->st_mutex); + entry = _mesa_hash_table_search(smPriv->stfbi_ht, stfbi); + mtx_unlock(&smPriv->st_mutex); + + return entry != NULL; +} + + +static boolean +st_framebuffer_iface_insert(struct st_manager *smapi, + struct st_framebuffer_iface *stfbi) +{ + struct st_manager_private *smPriv = + (struct st_manager_private *)smapi->st_manager_private; + struct hash_entry *entry; + + assert(smPriv); + assert(smPriv->stfbi_ht); + + mtx_lock(&smPriv->st_mutex); + entry = _mesa_hash_table_insert(smPriv->stfbi_ht, stfbi, stfbi); + mtx_unlock(&smPriv->st_mutex); + + return entry != NULL; +} + + +static void +st_framebuffer_iface_remove(struct st_manager *smapi, + struct st_framebuffer_iface *stfbi) +{ + struct st_manager_private *smPriv = + (struct st_manager_private *)smapi->st_manager_private; + struct hash_entry *entry; + + if (!smPriv || !smPriv->stfbi_ht) + return; + + mtx_lock(&smPriv->st_mutex); + entry = _mesa_hash_table_search(smPriv->stfbi_ht, stfbi); + if (!entry) + goto unlock; + + _mesa_hash_table_remove(smPriv->stfbi_ht, entry); + +unlock: + mtx_unlock(&smPriv->st_mutex); +} + + +/** + * The framebuffer interface object is no longer valid. + * Remove the object from the framebuffer interface hash table. + */ +static void +st_api_destroy_drawable(struct st_api *stapi, + struct st_framebuffer_iface *stfbi) +{ + if (!stfbi) + return; + + st_framebuffer_iface_remove(stfbi->state_manager, stfbi); +} + + +/** + * Purge the winsys buffers list to remove any references to + * non-existing framebuffer interface objects. + */ +static void +st_framebuffers_purge(struct st_context *st) +{ + struct st_context_iface *st_iface = &st->iface; + struct st_manager *smapi = st_iface->state_manager; + struct st_framebuffer *stfb, *next; + + assert(smapi); + + LIST_FOR_EACH_ENTRY_SAFE_REV(stfb, next, &st->winsys_buffers, head) { + struct st_framebuffer_iface *stfbi = stfb->iface; + + assert(stfbi); + + /** + * If the corresponding framebuffer interface object no longer exists, + * remove the framebuffer object from the context's winsys buffers list, + * and unreference the framebuffer object, so its resources can be + * deleted. + */ + if (!st_framebuffer_iface_lookup(smapi, stfbi)) { + LIST_DEL(&stfb->head); + st_framebuffer_reference(&stfb, NULL); + } + } +} + static void st_context_flush(struct st_context_iface *stctxi, unsigned flags, struct pipe_fence_handle **fence) @@ -498,8 +633,25 @@ st_context_flush(struct st_context_iface *stctxi, unsigned flags, } st_flush(st, fence, pipe_flags); + + if ((flags & ST_FLUSH_WAIT) && fence) { + st->pipe->screen->fence_finish(st->pipe->screen, NULL, *fence, + PIPE_TIMEOUT_INFINITE); + st->pipe->screen->fence_reference(st->pipe->screen, fence, NULL); + } + if (flags & ST_FLUSH_FRONT) st_manager_flush_frontbuffer(st); + + /* DRI3 changes the framebuffer after SwapBuffers, but we need to invoke + * st_manager_validate_framebuffers to notice that. + * + * Set gfx_shaders_may_be_dirty to invoke st_validate_state in the next + * draw call, which will invoke st_manager_validate_framebuffers, but it + * won't dirty states if there is no change. + */ + if (flags & ST_FLUSH_END_OF_FRAME) + st->gfx_shaders_may_be_dirty = true; } static boolean @@ -581,14 +733,13 @@ st_context_teximage(struct st_context_iface *stctxi, } pipe_resource_reference(&stImage->pt, tex); - stObj->width0 = width; - stObj->height0 = height; - stObj->depth0 = depth; stObj->surface_format = pipe_format; + stObj->needs_validation = true; + _mesa_dirty_texobj(ctx, texObj); _mesa_unlock_texture(ctx, texObj); - + return TRUE; } @@ -619,6 +770,22 @@ st_context_destroy(struct st_context_iface *stctxi) st_destroy_context(st); } +static void +st_start_thread(struct st_context_iface *stctxi) +{ + struct st_context *st = (struct st_context *) stctxi; + + _mesa_glthread_init(st->ctx); +} + +static void +st_thread_finish(struct st_context_iface *stctxi) +{ + struct st_context *st = (struct st_context *) stctxi; + + _mesa_glthread_finish(st->ctx); +} + static struct st_context_iface * st_api_create_context(struct st_api *stapi, struct st_manager *smapi, const struct st_context_attribs *attribs, @@ -630,6 +797,8 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi, struct pipe_context *pipe; struct gl_config mode; gl_api api; + bool no_error = false; + unsigned ctx_flags = PIPE_CONTEXT_PREFER_THREADED; if (!(stapi->profile_mask & (1 << attribs->profile))) return NULL; @@ -650,40 +819,73 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi, default: *error = ST_CONTEXT_ERROR_BAD_API; return NULL; - break; } - pipe = smapi->screen->context_create(smapi->screen, NULL); + /* Create a hash table for the framebuffer interface objects + * if it has not been created for this st manager. + */ + if (smapi->st_manager_private == NULL) { + struct st_manager_private *smPriv; + + smPriv = CALLOC_STRUCT(st_manager_private); + mtx_init(&smPriv->st_mutex, mtx_plain); + smPriv->stfbi_ht = _mesa_hash_table_create(NULL, + st_framebuffer_iface_hash, + st_framebuffer_iface_equal); + smapi->st_manager_private = smPriv; + smapi->destroy = st_manager_destroy; + } + + if (attribs->flags & ST_CONTEXT_FLAG_ROBUST_ACCESS) + ctx_flags |= PIPE_CONTEXT_ROBUST_BUFFER_ACCESS; + + if (attribs->flags & ST_CONTEXT_FLAG_NO_ERROR) + no_error = true; + + pipe = smapi->screen->context_create(smapi->screen, NULL, ctx_flags); if (!pipe) { *error = ST_CONTEXT_ERROR_NO_MEMORY; return NULL; } st_visual_to_context_mode(&attribs->visual, &mode); - st = st_create_context(api, pipe, &mode, shared_ctx, &attribs->options); + st = st_create_context(api, pipe, &mode, shared_ctx, &attribs->options, no_error); if (!st) { *error = ST_CONTEXT_ERROR_NO_MEMORY; pipe->destroy(pipe); return NULL; } - if (attribs->flags & ST_CONTEXT_FLAG_DEBUG){ + if (attribs->flags & ST_CONTEXT_FLAG_DEBUG) { if (!_mesa_set_debug_state_int(st->ctx, GL_DEBUG_OUTPUT, GL_TRUE)) { *error = ST_CONTEXT_ERROR_NO_MEMORY; return NULL; } + st->ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_DEBUG_BIT; } + if (st->ctx->Const.ContextFlags & GL_CONTEXT_FLAG_DEBUG_BIT) { + st_update_debug_callback(st); + } + if (attribs->flags & ST_CONTEXT_FLAG_FORWARD_COMPATIBLE) st->ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT; + if (attribs->flags & ST_CONTEXT_FLAG_ROBUST_ACCESS) { + st->ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB; + st->ctx->Const.RobustAccess = GL_TRUE; + } + if (attribs->flags & ST_CONTEXT_FLAG_RESET_NOTIFICATION_ENABLED) { + st->ctx->Const.ResetStrategy = GL_LOSE_CONTEXT_ON_RESET_ARB; + st_install_device_reset_callback(st); + } /* need to perform version check */ if (attribs->major > 1 || attribs->minor > 0) { /* Is the actual version less than the requested version? */ - if (st->ctx->Version < attribs->major * 10 + attribs->minor) { - *error = ST_CONTEXT_ERROR_BAD_VERSION; + if (st->ctx->Version < attribs->major * 10U + attribs->minor) { + *error = ST_CONTEXT_ERROR_BAD_VERSION; st_destroy_context(st); return NULL; } @@ -697,9 +899,12 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi, st->iface.teximage = st_context_teximage; st->iface.copy = st_context_copy; st->iface.share = st_context_share; + st->iface.start_thread = st_start_thread; + st->iface.thread_finish = st_thread_finish; st->iface.st_context_private = (void *) smapi; st->iface.cso_context = st->cso_context; st->iface.pipe = st->pipe; + st->iface.state_manager = smapi; *error = ST_CONTEXT_SUCCESS; return &st->iface; @@ -719,17 +924,39 @@ st_framebuffer_reuse_or_create(struct st_context *st, struct gl_framebuffer *fb, struct st_framebuffer_iface *stfbi) { - struct st_framebuffer *cur = st_ws_framebuffer(fb), *stfb = NULL; + struct st_framebuffer *cur = NULL, *stfb = NULL; + + if (!stfbi) + return NULL; - /* dummy framebuffers cant be used as st_framebuffer */ - if (cur && &cur->Base != _mesa_get_incomplete_framebuffer() && - cur->iface == stfbi) { - /* reuse the current stfb */ - st_framebuffer_reference(&stfb, cur); + /* Check if there is already a framebuffer object for the specified + * framebuffer interface in this context. If there is one, use it. + */ + LIST_FOR_EACH_ENTRY(cur, &st->winsys_buffers, head) { + if (cur->iface_ID == stfbi->ID) { + st_framebuffer_reference(&stfb, cur); + break; + } } - else { - /* create a new one */ - stfb = st_framebuffer_create(st, stfbi); + + /* If there is not already a framebuffer object, create one */ + if (stfb == NULL) { + cur = st_framebuffer_create(st, stfbi); + + if (cur) { + /* add the referenced framebuffer interface object to + * the framebuffer interface object hash table. + */ + if (!st_framebuffer_iface_insert(stfbi->state_manager, stfbi)) { + st_framebuffer_reference(&cur, NULL); + return NULL; + } + + /* add to the context's winsys buffers list */ + LIST_ADD(&cur->head, &st->winsys_buffers); + + st_framebuffer_reference(&stfb, cur); + } } return stfb; @@ -780,6 +1007,11 @@ st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi, st_framebuffer_reference(&stdraw, NULL); st_framebuffer_reference(&stread, NULL); + + /* Purge the context's winsys_buffers list in case any + * of the referenced drawables no longer exist. + */ + st_framebuffers_purge(st); } else { ret = _mesa_make_current(NULL, NULL, NULL); @@ -788,12 +1020,6 @@ st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi, return ret; } -static st_proc_t -st_api_get_proc_address(struct st_api *stapi, const char *procname) -{ - return (st_proc_t) _glapi_get_proc_address(procname); -} - static void st_api_destroy(struct st_api *stapi) { @@ -810,41 +1036,15 @@ st_manager_flush_frontbuffer(struct st_context *st) if (stfb) strb = st_renderbuffer(stfb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer); - if (!strb) - return; - - /* never a dummy fb */ - assert(&stfb->Base != _mesa_get_incomplete_framebuffer()); - stfb->iface->flush_front(&st->iface, stfb->iface, ST_ATTACHMENT_FRONT_LEFT); -} -/** - * Return the surface of an EGLImage. - * FIXME: I think this should operate on resources, not surfaces - */ -struct pipe_surface * -st_manager_get_egl_image_surface(struct st_context *st, void *eglimg) -{ - struct st_manager *smapi = - (struct st_manager *) st->iface.st_context_private; - struct st_egl_image stimg; - struct pipe_surface *ps, surf_tmpl; - - if (!smapi || !smapi->get_egl_image) - return NULL; - - memset(&stimg, 0, sizeof(stimg)); - if (!smapi->get_egl_image(smapi, eglimg, &stimg)) - return NULL; - - u_surface_default_template(&surf_tmpl, stimg.texture); - surf_tmpl.u.tex.level = stimg.level; - surf_tmpl.u.tex.first_layer = stimg.layer; - surf_tmpl.u.tex.last_layer = stimg.layer; - ps = st->pipe->create_surface(st->pipe, stimg.texture, &surf_tmpl); - pipe_resource_reference(&stimg.texture, NULL); - - return ps; + /* Do we have a front color buffer and has it been drawn to since last + * frontbuffer flush? + */ + if (strb && strb->defined) { + stfb->iface->flush_front(&st->iface, stfb->iface, + ST_ATTACHMENT_FRONT_LEFT); + strb->defined = GL_FALSE; + } } /** @@ -864,8 +1064,31 @@ st_manager_validate_framebuffers(struct st_context *st) st_context_validate(st, stdraw, stread); } + /** - * Add a color renderbuffer on demand. + * Flush any outstanding swapbuffers on the current draw framebuffer. + */ +void +st_manager_flush_swapbuffers(void) +{ + GET_CURRENT_CONTEXT(ctx); + struct st_context *st = (ctx) ? ctx->st : NULL; + struct st_framebuffer *stfb; + + if (!st) + return; + + stfb = st_ws_framebuffer(ctx->DrawBuffer); + if (!stfb || !stfb->iface->flush_swapbuffers) + return; + + stfb->iface->flush_swapbuffers(&st->iface, stfb->iface); +} + + +/** + * Add a color renderbuffer on demand. The FBO must correspond to a window, + * not a user-created FBO. */ boolean st_manager_add_color_renderbuffer(struct st_context *st, @@ -878,6 +1101,8 @@ st_manager_add_color_renderbuffer(struct st_context *st, if (!stfb) return FALSE; + assert(_mesa_is_winsys_fbo(fb)); + if (stfb->Base.Attachment[idx].Renderbuffer) return TRUE; @@ -889,7 +1114,6 @@ st_manager_add_color_renderbuffer(struct st_context *st, break; default: return FALSE; - break; } if (!st_framebuffer_add_renderbuffer(stfb, idx)) @@ -902,42 +1126,77 @@ st_manager_add_color_renderbuffer(struct st_context *st, * new renderbuffer. It might be that there is a window system * renderbuffer available. */ - if(stfb->iface) + if (stfb->iface) stfb->iface_stamp = p_atomic_read(&stfb->iface->stamp) - 1; - st_invalidate_state(st->ctx, _NEW_BUFFERS); + st_invalidate_buffers(st); return TRUE; } +static void +st_manager_destroy(struct st_manager *smapi) +{ + struct st_manager_private *smPriv = smapi->st_manager_private; + + if (smPriv && smPriv->stfbi_ht) { + _mesa_hash_table_destroy(smPriv->stfbi_ht, NULL); + mtx_destroy(&smPriv->st_mutex); + free(smPriv); + smapi->st_manager_private = NULL; + } +} + +static unsigned +get_version(struct pipe_screen *screen, + struct st_config_options *options, gl_api api) +{ + struct gl_constants consts = {0}; + struct gl_extensions extensions = {0}; + GLuint version; + + if (_mesa_override_gl_version_contextless(&consts, &api, &version)) { + return version; + } + + _mesa_init_constants(&consts, api); + _mesa_init_extensions(&extensions); + + st_init_limits(screen, &consts, &extensions); + st_init_extensions(screen, &consts, &extensions, options, GL_TRUE); + + return _mesa_get_version(&extensions, &consts, api); +} + static void st_api_query_versions(struct st_api *stapi, struct st_manager *sm, + struct st_config_options *options, int *gl_core_version, int *gl_compat_version, int *gl_es1_version, int *gl_es2_version) { - *gl_core_version = 33; - *gl_compat_version = 30; - *gl_es1_version = 11; - *gl_es2_version = 30; + *gl_core_version = get_version(sm->screen, options, API_OPENGL_CORE); + *gl_compat_version = get_version(sm->screen, options, API_OPENGL_COMPAT); + *gl_es1_version = get_version(sm->screen, options, API_OPENGLES); + *gl_es2_version = get_version(sm->screen, options, API_OPENGLES2); } static const struct st_api st_gl_api = { - "Mesa " PACKAGE_VERSION, - ST_API_OPENGL, - ST_PROFILE_DEFAULT_MASK | - ST_PROFILE_OPENGL_CORE_MASK | - ST_PROFILE_OPENGL_ES1_MASK | - ST_PROFILE_OPENGL_ES2_MASK | - 0, - ST_API_FEATURE_MS_VISUALS_MASK, - st_api_destroy, - st_api_query_versions, - st_api_get_proc_address, - st_api_create_context, - st_api_make_current, - st_api_get_current, + .name = "Mesa " PACKAGE_VERSION, + .api = ST_API_OPENGL, + .profile_mask = ST_PROFILE_DEFAULT_MASK | + ST_PROFILE_OPENGL_CORE_MASK | + ST_PROFILE_OPENGL_ES1_MASK | + ST_PROFILE_OPENGL_ES2_MASK | + 0, + .feature_mask = ST_API_FEATURE_MS_VISUALS_MASK, + .destroy = st_api_destroy, + .query_versions = st_api_query_versions, + .create_context = st_api_create_context, + .make_current = st_api_make_current, + .get_current = st_api_get_current, + .destroy_drawable = st_api_destroy_drawable, }; struct st_api *