summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2010-09-10 10:31:06 +0800
committerChia-I Wu <[email protected]>2010-09-10 15:37:43 +0800
commit4531356817ec8383ac35932903773de67af92e37 (patch)
treebb9c6262af2ca8261db6b0d325622d122ef04c70
parentfcae8ca57512f84c51b7445456aab7ec92a21254 (diff)
gallium: Add context profile support to st_api.
Add struct st_context_attribs to describe context profiles and attributes. Modify st_api::create_context to take the new struct instead of an st_visual. st_context_attribs can be used to support GLX_ARB_create_context_profile and GLX_EXT_create_context_es2_profile in the future. But the motivation for doing it now is to be able to replace ST_API_OPENGL_ES1 and ST_API_OPENGL_ES2 by profiles. Having 3 st_api's to provide OpenGL, OpenGL ES 1.1, and OpenGL ES 2.0 is not a sane abstraction, since all of them share glapi for current context/dispatch management.
-rw-r--r--src/gallium/include/state_tracker/st_api.h63
-rw-r--r--src/gallium/state_trackers/dri/common/dri_context.c10
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_api.c24
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.c7
-rw-r--r--src/gallium/state_trackers/vega/vg_manager.c11
-rw-r--r--src/gallium/state_trackers/wgl/stw_context.c7
-rw-r--r--src/mesa/main/version.c6
-rw-r--r--src/mesa/state_tracker/st_manager.c75
8 files changed, 171 insertions, 32 deletions
diff --git a/src/gallium/include/state_tracker/st_api.h b/src/gallium/include/state_tracker/st_api.h
index 11424611881..9e87c8e0d40 100644
--- a/src/gallium/include/state_tracker/st_api.h
+++ b/src/gallium/include/state_tracker/st_api.h
@@ -55,6 +55,23 @@ enum st_api_type {
};
/**
+ * The profile of a context.
+ */
+enum st_profile_type
+{
+ ST_PROFILE_DEFAULT,
+ ST_PROFILE_OPENGL_CORE,
+ ST_PROFILE_OPENGL_ES1,
+ ST_PROFILE_OPENGL_ES2
+};
+
+/* for profile_mask in st_api */
+#define ST_PROFILE_DEFAULT_MASK (1 << ST_PROFILE_DEFAULT)
+#define ST_PROFILE_OPENGL_CORE_MASK (1 << ST_PROFILE_OPENGL_CORE)
+#define ST_PROFILE_OPENGL_ES1_MASK (1 << ST_PROFILE_OPENGL_ES1)
+#define ST_PROFILE_OPENGL_ES2_MASK (1 << ST_PROFILE_OPENGL_ES2)
+
+/**
* Used in st_context_iface->teximage.
*/
enum st_texture_type {
@@ -180,6 +197,37 @@ struct st_visual
};
/**
+ * Represent the attributes of a context.
+ */
+struct st_context_attribs
+{
+ /**
+ * The profile and minimal version to support.
+ *
+ * The valid profiles and versions are rendering API dependent. The latest
+ * version satisfying the request should be returned, unless
+ * forward_compatiible is true.
+ */
+ enum st_profile_type profile;
+ int major, minor;
+
+ /**
+ * Enable debugging.
+ */
+ boolean debug;
+
+ /**
+ * Return the exact version and disallow the use of deprecated features.
+ */
+ boolean forward_compatible;
+
+ /**
+ * The visual of the framebuffers the context will be bound to.
+ */
+ struct st_visual visual;
+};
+
+/**
* Represent a windowing system drawable.
*
* The framebuffer is implemented by the state tracker manager and
@@ -357,6 +405,16 @@ struct st_manager
struct st_api
{
/**
+ * The supported rendering API.
+ */
+ enum st_api_type api;
+
+ /**
+ * The supported profiles. Tested with ST_PROFILE_*_MASK.
+ */
+ unsigned profile_mask;
+
+ /**
* Destroy the API.
*/
void (*destroy)(struct st_api *stapi);
@@ -373,13 +431,14 @@ struct st_api
*/
struct st_context_iface *(*create_context)(struct st_api *stapi,
struct st_manager *smapi,
- const struct st_visual *visual,
+ const struct st_context_attribs *attribs,
struct st_context_iface *stsharei);
/**
* Bind the context to the calling thread with draw and read as drawables.
*
- * The framebuffers might have different visuals than the context does.
+ * The framebuffers might be NULL, or might have different visuals than the
+ * context does.
*/
boolean (*make_current)(struct st_api *stapi,
struct st_context_iface *stctxi,
diff --git a/src/gallium/state_trackers/dri/common/dri_context.c b/src/gallium/state_trackers/dri/common/dri_context.c
index f9ebe1edcce..8948cfc2ccb 100644
--- a/src/gallium/state_trackers/dri/common/dri_context.c
+++ b/src/gallium/state_trackers/dri/common/dri_context.c
@@ -57,17 +57,21 @@ dri_create_context(gl_api api, const __GLcontextModes * visual,
struct st_api *stapi;
struct dri_context *ctx = NULL;
struct st_context_iface *st_share = NULL;
- struct st_visual stvis;
+ struct st_context_attribs attribs;
+ memset(&attribs, 0, sizeof(attribs));
switch (api) {
case API_OPENGL:
stapi = screen->st_api[ST_API_OPENGL];
+ attribs.profile = ST_PROFILE_DEFAULT;
break;
case API_OPENGLES:
stapi = screen->st_api[ST_API_OPENGL_ES1];
+ attribs.profile = ST_PROFILE_OPENGL_ES1;
break;
case API_OPENGLES2:
stapi = screen->st_api[ST_API_OPENGL_ES2];
+ attribs.profile = ST_PROFILE_OPENGL_ES2;
break;
default:
stapi = NULL;
@@ -92,8 +96,8 @@ dri_create_context(gl_api api, const __GLcontextModes * visual,
driParseConfigFiles(&ctx->optionCache,
&screen->optionCache, sPriv->myNum, "dri");
- dri_fill_st_visual(&stvis, screen, visual);
- ctx->st = stapi->create_context(stapi, &screen->base, &stvis, st_share);
+ dri_fill_st_visual(&attribs.visual, screen, visual);
+ ctx->st = stapi->create_context(stapi, &screen->base, &attribs, st_share);
if (ctx->st == NULL)
goto fail;
ctx->st->st_manager_private = (void *) ctx;
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.c b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
index 3ec53653f44..cda46b8c301 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
@@ -43,7 +43,8 @@
* Return the state tracker for the given context.
*/
static struct st_api *
-egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx)
+egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx,
+ enum st_profile_type *profile)
{
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
EGLint idx = -1;
@@ -74,6 +75,18 @@ egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx)
break;
}
+ switch (idx) {
+ case ST_API_OPENGL_ES1:
+ *profile = ST_PROFILE_OPENGL_ES1;
+ break;
+ case ST_API_OPENGL_ES2:
+ *profile = ST_PROFILE_OPENGL_ES2;
+ break;
+ default:
+ *profile = ST_PROFILE_DEFAULT;
+ break;
+ }
+
return (idx >= 0) ? gdrv->loader->get_st_api(idx) : NULL;
}
@@ -85,6 +98,7 @@ egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
struct egl_g3d_context *gshare = egl_g3d_context(share);
struct egl_g3d_config *gconf = egl_g3d_config(conf);
struct egl_g3d_context *gctx;
+ struct st_context_attribs stattribs;
gctx = CALLOC_STRUCT(egl_g3d_context);
if (!gctx) {
@@ -97,14 +111,18 @@ egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
return NULL;
}
- gctx->stapi = egl_g3d_choose_st(drv, &gctx->base);
+ memset(&stattribs, 0, sizeof(stattribs));
+ if (gconf)
+ stattribs.visual = gconf->stvis;
+
+ gctx->stapi = egl_g3d_choose_st(drv, &gctx->base, &stattribs.profile);
if (!gctx->stapi) {
FREE(gctx);
return NULL;
}
gctx->stctxi = gctx->stapi->create_context(gctx->stapi, gdpy->smapi,
- (gconf) ? &gconf->stvis : NULL, (gshare) ? gshare->stctxi : NULL);
+ &stattribs, (gshare) ? gshare->stctxi : NULL);
if (!gctx->stctxi) {
FREE(gctx);
return NULL;
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c
index eb4ce742669..36d63c30d6c 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.c
@@ -849,6 +849,7 @@ PUBLIC
XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
{
XMesaDisplay xmdpy = xmesa_init_display(v->display);
+ struct st_context_attribs attribs;
XMesaContext c;
if (!xmdpy)
@@ -863,8 +864,12 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */
c->xm_read_buffer = NULL;
+ memset(&attribs, 0, sizeof(attribs));
+ attribs.profile = ST_PROFILE_DEFAULT;
+ attribs.visual = v->stvis;
+
c->st = stapi->create_context(stapi, xmdpy->smapi,
- &v->stvis, (share_list) ? share_list->st : NULL);
+ &attribs, (share_list) ? share_list->st : NULL);
if (c->st == NULL)
goto fail;
diff --git a/src/gallium/state_trackers/vega/vg_manager.c b/src/gallium/state_trackers/vega/vg_manager.c
index c2aa98b231c..e7996741d14 100644
--- a/src/gallium/state_trackers/vega/vg_manager.c
+++ b/src/gallium/state_trackers/vega/vg_manager.c
@@ -341,13 +341,20 @@ vg_context_destroy(struct st_context_iface *stctxi)
static struct st_context_iface *
vg_api_create_context(struct st_api *stapi, struct st_manager *smapi,
- const struct st_visual *visual,
+ const struct st_context_attribs *attribs,
struct st_context_iface *shared_stctxi)
{
struct vg_context *shared_ctx = (struct vg_context *) shared_stctxi;
struct vg_context *ctx;
struct pipe_context *pipe;
+ if (!(stapi->profile_mask & (1 << attribs->profile)))
+ return NULL;
+
+ /* only 1.0 is supported */
+ if (attribs->major != 1 || attribs->minor > 0)
+ return NULL;
+
pipe = smapi->screen->context_create(smapi->screen, NULL);
if (!pipe)
return NULL;
@@ -528,6 +535,8 @@ vg_api_destroy(struct st_api *stapi)
}
static const struct st_api vg_api = {
+ ST_API_OPENVG,
+ ST_PROFILE_DEFAULT_MASK,
vg_api_destroy,
vg_api_get_proc_address,
vg_api_create_context,
diff --git a/src/gallium/state_trackers/wgl/stw_context.c b/src/gallium/state_trackers/wgl/stw_context.c
index a0e14b96016..85878b46730 100644
--- a/src/gallium/state_trackers/wgl/stw_context.c
+++ b/src/gallium/state_trackers/wgl/stw_context.c
@@ -129,6 +129,7 @@ DrvCreateLayerContext(
{
int iPixelFormat;
const struct stw_pixelformat_info *pfi;
+ struct st_context_attribs attribs;
struct stw_context *ctx = NULL;
if(!stw_dev)
@@ -150,8 +151,12 @@ DrvCreateLayerContext(
ctx->hdc = hdc;
ctx->iPixelFormat = iPixelFormat;
+ memset(&attribs, 0, sizeof(attribs));
+ attribs.profile = ST_PROFILE_DEFAULT;
+ attribs.visual = pfi->stvis;
+
ctx->st = stw_dev->stapi->create_context(stw_dev->stapi,
- stw_dev->smapi, &pfi->stvis, NULL);
+ stw_dev->smapi, &attribs, NULL);
if (ctx->st == NULL)
goto no_st_ctx;
diff --git a/src/mesa/main/version.c b/src/mesa/main/version.c
index d833a160e9e..9e1f5f2a4fe 100644
--- a/src/mesa/main/version.c
+++ b/src/mesa/main/version.c
@@ -260,11 +260,15 @@ compute_version_es2(GLcontext *ctx)
/**
* Set the context's VersionMajor, VersionMinor, VersionString fields.
- * This should only be called once as part of context initialization.
+ * This should only be called once as part of context initialization
+ * or to perform version check for GLX_ARB_create_context_profile.
*/
void
_mesa_compute_version(GLcontext *ctx)
{
+ if (ctx->VersionMajor)
+ return;
+
switch (ctx->API) {
case API_OPENGL:
compute_version(ctx);
diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c
index ccce574c364..8acd0938bb8 100644
--- a/src/mesa/state_tracker/st_manager.c
+++ b/src/mesa/state_tracker/st_manager.c
@@ -44,6 +44,7 @@
#include "main/framebuffer.h"
#include "main/fbobject.h"
#include "main/renderbuffer.h"
+#include "main/version.h"
#include "st_texture.h"
#include "st_context.h"
@@ -303,10 +304,6 @@ st_visual_to_context_mode(const struct st_visual *visual,
{
memset(mode, 0, sizeof(*mode));
- /* FBO-only context */
- if (!visual)
- return;
-
if (st_visual_have_buffers(visual, ST_ATTACHMENT_BACK_LEFT_MASK))
mode->doubleBufferMode = GL_TRUE;
if (st_visual_have_buffers(visual,
@@ -612,26 +609,57 @@ st_context_destroy(struct st_context_iface *stctxi)
}
static struct st_context_iface *
-create_context(gl_api api, struct st_manager *smapi,
- const struct st_visual *visual,
- struct st_context_iface *shared_stctxi)
+st_api_create_context(struct st_api *stapi, struct st_manager *smapi,
+ const struct st_context_attribs *attribs,
+ struct st_context_iface *shared_stctxi)
{
struct st_context *shared_ctx = (struct st_context *) shared_stctxi;
struct st_context *st;
struct pipe_context *pipe;
__GLcontextModes mode;
+ gl_api api;
+
+ if (!(stapi->profile_mask & (1 << attribs->profile)))
+ return NULL;
+
+ switch (attribs->profile) {
+ case ST_PROFILE_DEFAULT:
+ api = API_OPENGL;
+ break;
+ case ST_PROFILE_OPENGL_ES1:
+ api = API_OPENGLES;
+ break;
+ case ST_PROFILE_OPENGL_ES2:
+ api = API_OPENGLES2;
+ break;
+ case ST_PROFILE_OPENGL_CORE:
+ default:
+ return NULL;
+ break;
+ }
pipe = smapi->screen->context_create(smapi->screen, NULL);
if (!pipe)
return NULL;
- st_visual_to_context_mode(visual, &mode);
+ st_visual_to_context_mode(&attribs->visual, &mode);
st = st_create_context(api, pipe, &mode, shared_ctx);
if (!st) {
pipe->destroy(pipe);
return NULL;
}
+ /* need to perform version check */
+ if (attribs->major > 1 || attribs->minor > 0) {
+ _mesa_compute_version(st->ctx);
+
+ if (st->ctx->VersionMajor < attribs->major ||
+ st->ctx->VersionMajor < attribs->minor) {
+ st_destroy_context(st);
+ return NULL;
+ }
+ }
+
st->invalidate_on_gl_viewport =
smapi->get_param(smapi, ST_MANAGER_BROKEN_INVALIDATE);
@@ -647,27 +675,19 @@ create_context(gl_api api, struct st_manager *smapi,
}
static struct st_context_iface *
-st_api_create_context(struct st_api *stapi, struct st_manager *smapi,
- const struct st_visual *visual,
- struct st_context_iface *shared_stctxi)
-{
- return create_context(API_OPENGL, smapi, visual, shared_stctxi);
-}
-
-static struct st_context_iface *
st_api_create_context_es1(struct st_api *stapi, struct st_manager *smapi,
- const struct st_visual *visual,
+ const struct st_context_attribs *attribs,
struct st_context_iface *shared_stctxi)
{
- return create_context(API_OPENGLES, smapi, visual, shared_stctxi);
+ return st_api_create_context(stapi, smapi, attribs, shared_stctxi);
}
static struct st_context_iface *
st_api_create_context_es2(struct st_api *stapi, struct st_manager *smapi,
- const struct st_visual *visual,
+ const struct st_context_attribs *attribs,
struct st_context_iface *shared_stctxi)
{
- return create_context(API_OPENGLES2, smapi, visual, shared_stctxi);
+ return st_api_create_context(stapi, smapi, attribs, shared_stctxi);
}
static boolean
@@ -852,6 +872,17 @@ st_manager_add_color_renderbuffer(struct st_context *st, GLframebuffer *fb,
}
static const struct st_api st_gl_api = {
+ ST_API_OPENGL,
+#if FEATURE_GL
+ ST_PROFILE_DEFAULT_MASK |
+#endif
+#if FEATURE_ES1
+ ST_PROFILE_OPENGL_ES1_MASK |
+#endif
+#if FEATURE_ES2
+ ST_PROFILE_OPENGL_ES2_MASK |
+#endif
+ 0,
st_api_destroy,
st_api_get_proc_address,
st_api_create_context,
@@ -860,6 +891,8 @@ static const struct st_api st_gl_api = {
};
static const struct st_api st_gl_api_es1 = {
+ ST_API_OPENGL_ES1,
+ ST_PROFILE_OPENGL_ES1_MASK,
st_api_destroy,
st_api_get_proc_address,
st_api_create_context_es1,
@@ -868,6 +901,8 @@ static const struct st_api st_gl_api_es1 = {
};
static const struct st_api st_gl_api_es2 = {
+ ST_API_OPENGL_ES2,
+ ST_PROFILE_OPENGL_ES2_MASK,
st_api_destroy,
st_api_get_proc_address,
st_api_create_context_es2,