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

Reply via email to