dri_context.c revision 421235d42ad9921fd45332ec7b33bcee5c1ad33d
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************** 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright 2009, VMware, Inc. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * All Rights Reserved. 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Permission is hereby granted, free of charge, to any person obtaining a 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * copy of this software and associated documentation files (the 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "Software"), to deal in the Software without restriction, including 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * without limitation the rights to use, copy, modify, merge, publish, 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * distribute, sub license, and/or sell copies of the Software, and to 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * permit persons to whom the Software is furnished to do so, subject to 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the following conditions: 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The above copyright notice and this permission notice (including the 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * next paragraph) shall be included in all copies or substantial portions 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of the Software. 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) **************************************************************************/ 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Author: Keith Whitwell <keithw@vmware.com> 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Author: Jakob Bornecrantz <wallbraker@gmail.com> 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32#include "utils.h" 33 34#include "dri_screen.h" 35#include "dri_drawable.h" 36#include "dri_context.h" 37 38#include "pipe/p_context.h" 39#include "state_tracker/st_context.h" 40 41static void 42dri_init_extensions(struct dri_context *ctx) 43{ 44 struct st_context *st = (struct st_context *) ctx->st; 45 46 /* New extensions should be added in mesa/state_tracker/st_extensions.c 47 * and not in this file. */ 48 driInitExtensions(st->ctx, NULL, GL_FALSE); 49} 50 51static void 52dri_pp_query(struct dri_context *ctx) 53{ 54 unsigned int i; 55 56 for (i = 0; i < PP_FILTERS; i++) { 57 ctx->pp_enabled[i] = driQueryOptioni(&ctx->optionCache, pp_filters[i].name); 58 } 59} 60 61GLboolean 62dri_create_context(gl_api api, const struct gl_config * visual, 63 __DRIcontext * cPriv, void *sharedContextPrivate) 64{ 65 __DRIscreen *sPriv = cPriv->driScreenPriv; 66 struct dri_screen *screen = dri_screen(sPriv); 67 struct st_api *stapi = screen->st_api; 68 struct dri_context *ctx = NULL; 69 struct st_context_iface *st_share = NULL; 70 struct st_context_attribs attribs; 71 72 memset(&attribs, 0, sizeof(attribs)); 73 switch (api) { 74 case API_OPENGLES: 75 attribs.profile = ST_PROFILE_OPENGL_ES1; 76 break; 77 case API_OPENGLES2: 78 attribs.profile = ST_PROFILE_OPENGL_ES2; 79 break; 80 default: 81 attribs.profile = ST_PROFILE_DEFAULT; 82 break; 83 } 84 85 if (sharedContextPrivate) { 86 st_share = ((struct dri_context *)sharedContextPrivate)->st; 87 } 88 89 ctx = CALLOC_STRUCT(dri_context); 90 if (ctx == NULL) 91 goto fail; 92 93 cPriv->driverPrivate = ctx; 94 ctx->cPriv = cPriv; 95 ctx->sPriv = sPriv; 96 ctx->lock = screen->drmLock; 97 98 driParseConfigFiles(&ctx->optionCache, 99 &screen->optionCache, sPriv->myNum, "dri"); 100 101 dri_fill_st_visual(&attribs.visual, screen, visual); 102 ctx->st = stapi->create_context(stapi, &screen->base, &attribs, st_share); 103 if (ctx->st == NULL) 104 goto fail; 105 ctx->st->st_manager_private = (void *) ctx; 106 ctx->stapi = stapi; 107 108 /* 109 * libmesagallium.a that this state tracker will be linked to expects 110 * OpenGL's _glapi_table. That is, it expects libGL.so instead of 111 * libGLESv1_CM.so or libGLESv2.so. As there is no clean way to know the 112 * shared library the app links to, use the api as a simple check. 113 * It might be as well to simply remove this function call though. 114 */ 115 if (api == API_OPENGL) 116 dri_init_extensions(ctx); 117 118 // Context successfully created. See if post-processing is requested. 119 dri_pp_query(ctx); 120 121 ctx->pp = pp_init(screen->base.screen, ctx->pp_enabled); 122 123 return GL_TRUE; 124 125 fail: 126 if (ctx && ctx->st) 127 ctx->st->destroy(ctx->st); 128 129 FREE(ctx); 130 return GL_FALSE; 131} 132 133void 134dri_destroy_context(__DRIcontext * cPriv) 135{ 136 struct dri_context *ctx = dri_context(cPriv); 137 138 /* note: we are freeing values and nothing more because 139 * driParseConfigFiles allocated values only - the rest 140 * is owned by screen optionCache. 141 */ 142 FREE(ctx->optionCache.values); 143 144 /* No particular reason to wait for command completion before 145 * destroying a context, but it is probably worthwhile flushing it 146 * to avoid having to add code elsewhere to cope with flushing a 147 * partially destroyed context. 148 */ 149 ctx->st->flush(ctx->st, 0, NULL); 150 ctx->st->destroy(ctx->st); 151 152 if (ctx->pp) pp_free(ctx->pp); 153 154 FREE(ctx); 155} 156 157GLboolean 158dri_unbind_context(__DRIcontext * cPriv) 159{ 160 /* dri_util.c ensures cPriv is not null */ 161 struct dri_screen *screen = dri_screen(cPriv->driScreenPriv); 162 struct dri_context *ctx = dri_context(cPriv); 163 struct st_api *stapi = screen->st_api; 164 165 if (--ctx->bind_count == 0) { 166 if (ctx->st == ctx->stapi->get_current(ctx->stapi)) { 167 ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL); 168 stapi->make_current(stapi, NULL, NULL, NULL); 169 } 170 } 171 172 return GL_TRUE; 173} 174 175GLboolean 176dri_make_current(__DRIcontext * cPriv, 177 __DRIdrawable * driDrawPriv, 178 __DRIdrawable * driReadPriv) 179{ 180 /* dri_util.c ensures cPriv is not null */ 181 struct dri_context *ctx = dri_context(cPriv); 182 struct dri_drawable *draw = dri_drawable(driDrawPriv); 183 struct dri_drawable *read = dri_drawable(driReadPriv); 184 struct st_context_iface *old_st = ctx->stapi->get_current(ctx->stapi); 185 186 if (old_st && old_st != ctx->st) 187 old_st->flush(old_st, ST_FLUSH_FRONT, NULL); 188 189 ++ctx->bind_count; 190 191 if (!driDrawPriv && !driReadPriv) 192 return ctx->stapi->make_current(ctx->stapi, ctx->st, NULL, NULL); 193 else if (!driDrawPriv || !driReadPriv) 194 return GL_FALSE; 195 196 if (ctx->dPriv != driDrawPriv) { 197 ctx->dPriv = driDrawPriv; 198 draw->texture_stamp = driDrawPriv->lastStamp - 1; 199 } 200 if (ctx->rPriv != driReadPriv) { 201 ctx->rPriv = driReadPriv; 202 read->texture_stamp = driReadPriv->lastStamp - 1; 203 } 204 205 ctx->stapi->make_current(ctx->stapi, ctx->st, &draw->base, &read->base); 206 207 // This is ok to call here. If they are already init, it's a no-op. 208 if (draw->textures[ST_ATTACHMENT_BACK_LEFT] && draw->textures[ST_ATTACHMENT_DEPTH_STENCIL] 209 && ctx->pp) 210 pp_init_fbos(ctx->pp, draw->textures[ST_ATTACHMENT_BACK_LEFT]->width0, 211 draw->textures[ST_ATTACHMENT_BACK_LEFT]->height0, 212 draw->textures[ST_ATTACHMENT_DEPTH_STENCIL]); 213 214 return GL_TRUE; 215} 216 217struct dri_context * 218dri_get_current(__DRIscreen *sPriv) 219{ 220 struct dri_screen *screen = dri_screen(sPriv); 221 struct st_api *stapi = screen->st_api; 222 struct st_context_iface *st; 223 224 st = stapi->get_current(stapi); 225 226 return (struct dri_context *) (st) ? st->st_manager_private : NULL; 227} 228 229/* vim: set sw=3 ts=8 sts=3 expandtab: */ 230