The first patch fixes a current bug, the second naively integrates support for ES 1 and ES 2 into Gallium DRI drivers: 1. st/dri: Make clear which API's are supported (aka just desktop GL) 2. st/dri: Add multi-api support (applies after the first patch)
One issue with patch 2, though, is implementing dri_get_current() -- it calls a vfunc on a struct st_api object, but the st_api object is API-specific, and the dri_get_current function is called on a dri screen--which could support multiple API's. So for now it has to guess which API's implementation of get_current to use -- currently, all three use the same implementation, so this isn't a real problem yet. Should get_current() be moved out of struct st_api though?
From 9b5b5fc1bf5d21222ca66f41539eb1a6e908a5e7 Mon Sep 17 00:00:00 2001 From: nobled <nob...@dreamwidth.org> Date: Tue, 7 Sep 2010 12:10:45 -0400 Subject: [PATCH 1/2] st/dri: Make clear which API's are supported If the caller requests a GLES context, don't silently create a desktop GL context in its place. --- .../state_trackers/dri/common/dri_context.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/src/gallium/state_trackers/dri/common/dri_context.c b/src/gallium/state_trackers/dri/common/dri_context.c index 203682e..931cffa 100644 --- a/src/gallium/state_trackers/dri/common/dri_context.c +++ b/src/gallium/state_trackers/dri/common/dri_context.c @@ -59,6 +59,9 @@ dri_create_context(gl_api api, const __GLcontextModes * visual, struct st_context_iface *st_share = NULL; struct st_visual stvis; + if (api != API_OPENGL) + return GL_FALSE; + if (sharedContextPrivate) { st_share = ((struct dri_context *)sharedContextPrivate)->st; } @@ -90,7 +93,7 @@ dri_create_context(gl_api api, const __GLcontextModes * visual, ctx->st->destroy(ctx->st); FREE(ctx); - return FALSE; + return GL_FALSE; } void -- 1.7.0.4
From 73bf16bb135b8680e2374c4849f38026883f9b67 Mon Sep 17 00:00:00 2001 From: nobled <nob...@dreamwidth.org> Date: Mon, 30 Aug 2010 20:23:54 +0000 Subject: [PATCH 2/2] st/dri: Add multi-api support Make st/dri screens capable of creating OpenGL ES and OpenGL ES2 contexts. TODO: Figure out the "get_current" problem with multiple st_api's for real. --- .../state_trackers/dri/common/dri_context.c | 33 +++++++++++++++----- .../state_trackers/dri/common/dri_context.h | 1 + src/gallium/state_trackers/dri/common/dri_screen.c | 15 ++++++-- src/gallium/state_trackers/dri/common/dri_screen.h | 2 +- src/gallium/state_trackers/dri/drm/dri2.c | 8 +++++ 5 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/gallium/state_trackers/dri/common/dri_context.c b/src/gallium/state_trackers/dri/common/dri_context.c index 931cffa..6a8e3b0 100644 --- a/src/gallium/state_trackers/dri/common/dri_context.c +++ b/src/gallium/state_trackers/dri/common/dri_context.c @@ -54,12 +54,14 @@ dri_create_context(gl_api api, const __GLcontextModes * visual, { __DRIscreen *sPriv = cPriv->driScreenPriv; struct dri_screen *screen = dri_screen(sPriv); - struct st_api *stapi = screen->st_api; + struct st_api *stapi; struct dri_context *ctx = NULL; struct st_context_iface *st_share = NULL; struct st_visual stvis; - if (api != API_OPENGL) + assert(api <= API_OPENGLES2); + stapi = screen->st_api[api]; + if (!stapi) return GL_FALSE; if (sharedContextPrivate) { @@ -71,6 +73,7 @@ dri_create_context(gl_api api, const __GLcontextModes * visual, goto fail; cPriv->driverPrivate = ctx; + ctx->api = api; ctx->cPriv = cPriv; ctx->sPriv = sPriv; ctx->lock = screen->drmLock; @@ -124,7 +127,7 @@ dri_unbind_context(__DRIcontext * cPriv) /* dri_util.c ensures cPriv is not null */ struct dri_screen *screen = dri_screen(cPriv->driScreenPriv); struct dri_context *ctx = dri_context(cPriv); - struct st_api *stapi = screen->st_api; + struct st_api *stapi = screen->st_api[ctx->api]; if (--ctx->bind_count == 0) { if (ctx->st == stapi->get_current(stapi)) { @@ -144,7 +147,7 @@ dri_make_current(__DRIcontext * cPriv, /* dri_util.c ensures cPriv is not null */ struct dri_screen *screen = dri_screen(cPriv->driScreenPriv); struct dri_context *ctx = dri_context(cPriv); - struct st_api *stapi = screen->st_api; + struct st_api *stapi = screen->st_api[ctx->api]; struct dri_drawable *draw = dri_drawable(driDrawPriv); struct dri_drawable *read = dri_drawable(driReadPriv); struct st_context_iface *old_st = stapi->get_current(stapi); @@ -172,10 +175,24 @@ struct dri_context * dri_get_current(__DRIscreen *sPriv) { struct dri_screen *screen = dri_screen(sPriv); - struct st_api *stapi = screen->st_api; - struct st_context_iface *st; - - st = stapi->get_current(stapi); + struct st_api *stapi; + struct st_context_iface *st = NULL; + gl_api api; + + /* XXX: How do we do this when the screen supports + multiple rendering API's? Pick the first one, + like this? (NB: all three API's use the same + implementation of get_current (see st_manager.c), + so maybe it doesn't matter right now since + they'll all return the same result.) */ + for (api = API_OPENGL; api <= API_OPENGLES2; ++api) { + stapi = screen->st_api[api]; + if (!stapi) + continue; + st = stapi->get_current(stapi); + if (st) + break; + } return (struct dri_context *) (st) ? st->st_manager_private : NULL; } diff --git a/src/gallium/state_trackers/dri/common/dri_context.h b/src/gallium/state_trackers/dri/common/dri_context.h index 35b870a..7b92e7a 100644 --- a/src/gallium/state_trackers/dri/common/dri_context.h +++ b/src/gallium/state_trackers/dri/common/dri_context.h @@ -58,6 +58,7 @@ struct dri_context unsigned int bind_count; /* gallium */ + gl_api api; struct st_context_iface *st; /* hooks filled in by dri2 & drisw */ diff --git a/src/gallium/state_trackers/dri/common/dri_screen.c b/src/gallium/state_trackers/dri/common/dri_screen.c index 0ab4dd1..853ee1e 100644 --- a/src/gallium/state_trackers/dri/common/dri_screen.c +++ b/src/gallium/state_trackers/dri/common/dri_screen.c @@ -344,8 +344,10 @@ dri_destroy_option_cache(struct dri_screen * screen) void dri_destroy_screen_helper(struct dri_screen * screen) { - if (screen->st_api && screen->st_api->destroy) - screen->st_api->destroy(screen->st_api); + gl_api api; + for (api = API_OPENGL; api <= API_OPENGLES2; ++api) + if (screen->st_api[api] && screen->st_api[api]->destroy) + screen->st_api[api]->destroy(screen->st_api[api]); if (screen->base.screen) screen->base.screen->destroy(screen->base.screen); @@ -378,9 +380,14 @@ dri_init_screen_helper(struct dri_screen *screen, screen->base.get_egl_image = dri_get_egl_image; screen->base.get_param = dri_get_param; - screen->st_api = st_gl_api_create(); - if (!screen->st_api) + screen->st_api[API_OPENGL] = st_gl_api_create(); + screen->st_api[API_OPENGLES1] = st_gl_api_create_es1(); + screen->st_api[API_OPENGLES2] = st_gl_api_create_es2(); + + if (!screen->st_api[API_OPENGL] && + !screen->st_api[API_OPENGLES1] && + !screen->st_api[API_OPENGLES2]) return NULL; if(pscreen->get_param(pscreen, PIPE_CAP_NPOT_TEXTURES)) diff --git a/src/gallium/state_trackers/dri/common/dri_screen.h b/src/gallium/state_trackers/dri/common/dri_screen.h index 849f399..4141461 100644 --- a/src/gallium/state_trackers/dri/common/dri_screen.h +++ b/src/gallium/state_trackers/dri/common/dri_screen.h @@ -47,7 +47,7 @@ struct dri_screen { /* st_api */ struct st_manager base; - struct st_api *st_api; + struct st_api *st_api[1+API_OPENGLES2]; /* GL, GLES1, GLES2 */ /* on old libGL's invalidate doesn't get called as it should */ boolean broken_invalidate; diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c index 93f910a..7a56788 100644 --- a/src/gallium/state_trackers/dri/drm/dri2.c +++ b/src/gallium/state_trackers/dri/drm/dri2.c @@ -439,6 +439,14 @@ dri2_init_screen(__DRIscreen * sPriv) if (!configs) goto fail; + sPriv->api_mask = 0; + if (screen->st_api[API_OPENGL]) + sPriv->api_mask |= 1 << __DRI_API_OPENGL; + if (screen->st_api[API_OPENGLES1]) + sPriv->api_mask |= 1 << __DRI_API_GLES; + if (screen->st_api[API_OPENGLES2]) + sPriv->api_mask |= 1 << __DRI_API_GLES2; + screen->auto_fake_front = dri_with_format(sPriv); screen->broken_invalidate = !sPriv->dri2.useInvalidate; -- 1.7.0.4
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev