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