mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 02:38:04 +02:00
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.
This commit is contained in:
parent
fcae8ca575
commit
4531356817
8 changed files with 171 additions and 32 deletions
|
|
@ -54,6 +54,23 @@ enum st_api_type {
|
|||
ST_API_COUNT
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
|
@ -179,6 +196,37 @@ struct st_visual
|
|||
enum st_attachment_type render_buffer;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
|
|
@ -356,6 +404,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.
|
||||
*/
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
@ -646,28 +674,20 @@ create_context(gl_api api, struct st_manager *smapi,
|
|||
return &st->iface;
|
||||
}
|
||||
|
||||
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,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue