Merge remote branch 'main/master' into radeon-rewrite
[mesa.git] / src / gallium / state_trackers / dri2 / dri_context.c
1 /**************************************************************************
2 *
3 * Copyright 2009, VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27 /*
28 * Author: Keith Whitwell <keithw@vmware.com>
29 * Author: Jakob Bornecrantz <wallbraker@gmail.com>
30 */
31
32 #include "dri_screen.h"
33
34 #include "dri_drawable.h"
35
36
37 #include "state_tracker/drm_api.h"
38 #include "state_tracker/st_public.h"
39 #include "state_tracker/st_context.h"
40 #include "pipe/p_context.h"
41
42 #include "dri_context.h"
43
44 #include "util/u_memory.h"
45
46
47 GLboolean
48 dri_create_context(const __GLcontextModes *visual,
49 __DRIcontextPrivate *cPriv,
50 void *sharedContextPrivate)
51 {
52 __DRIscreenPrivate *sPriv = cPriv->driScreenPriv;
53 struct dri_screen *screen = dri_screen(sPriv);
54 struct dri_context *ctx = NULL;
55 struct st_context *st_share = NULL;
56
57 if (sharedContextPrivate) {
58 st_share = ((struct dri_context *) sharedContextPrivate)->st;
59 }
60
61 ctx = CALLOC_STRUCT(dri_context);
62 if (ctx == NULL)
63 goto fail;
64
65 cPriv->driverPrivate = ctx;
66 ctx->cPriv = cPriv;
67 ctx->sPriv = sPriv;
68
69 driParseConfigFiles(&ctx->optionCache,
70 &screen->optionCache,
71 sPriv->myNum,
72 "dri");
73
74 ctx->pipe = drm_api_hooks.create_context(screen->pipe_screen);
75
76 if (ctx->pipe == NULL)
77 goto fail;
78
79 /* used in dri_flush_frontbuffer */
80 ctx->pipe->priv = ctx;
81
82 ctx->st = st_create_context(ctx->pipe, visual, st_share);
83 if (ctx->st == NULL)
84 goto fail;
85
86 dri_init_extensions(ctx);
87
88 return GL_TRUE;
89
90 fail:
91 if (ctx && ctx->st)
92 st_destroy_context(ctx->st);
93
94 if (ctx && ctx->pipe)
95 ctx->pipe->destroy(ctx->pipe);
96
97 FREE(ctx);
98 return FALSE;
99 }
100
101
102 void
103 dri_destroy_context(__DRIcontextPrivate *cPriv)
104 {
105 struct dri_context *ctx = dri_context(cPriv);
106 struct dri_screen *screen = dri_screen(cPriv->driScreenPriv);
107
108 /* No particular reason to wait for command completion before
109 * destroying a context, but it is probably worthwhile flushing it
110 * to avoid having to add code elsewhere to cope with flushing a
111 * partially destroyed context.
112 */
113 st_flush(ctx->st, 0, NULL);
114
115 if (screen->dummyContext == ctx)
116 screen->dummyContext = NULL;
117
118 /* Also frees ctx->pipe?
119 */
120 st_destroy_context(ctx->st);
121
122 FREE(ctx);
123 }
124
125
126 GLboolean
127 dri_unbind_context(__DRIcontextPrivate *cPriv)
128 {
129 struct dri_context *ctx = dri_context(cPriv);
130 st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
131 /* XXX make_current(NULL)? */
132 return GL_TRUE;
133 }
134
135
136 GLboolean
137 dri_make_current(__DRIcontextPrivate *cPriv,
138 __DRIdrawablePrivate *driDrawPriv,
139 __DRIdrawablePrivate *driReadPriv)
140 {
141 if (cPriv) {
142 struct dri_context *ctx = dri_context(cPriv);
143 struct dri_screen *screen = dri_screen(cPriv->driScreenPriv);
144 struct dri_drawable *draw = dri_drawable(driDrawPriv);
145 struct dri_drawable *read = dri_drawable(driReadPriv);
146
147 /* This is for situations in which we need a rendering context but
148 * there may not be any currently bound.
149 */
150 screen->dummyContext = ctx;
151
152 st_make_current(ctx->st,
153 draw->stfb,
154 read->stfb);
155
156 /* used in dri_flush_frontbuffer */
157 ctx->dPriv = driDrawPriv;
158
159 if (driDrawPriv)
160 dri_get_buffers(driDrawPriv);
161 if (driDrawPriv != driReadPriv && driReadPriv)
162 dri_get_buffers(driReadPriv);
163 } else {
164 st_make_current(NULL, NULL, NULL);
165 }
166
167 return GL_TRUE;
168 }
169
170 /* vim: set sw=3 ts=8 sts=3 expandtab: */