gallium: Update the dri2 state tracker to support dri1.
[mesa.git] / src / gallium / state_trackers / dri / dri_screen.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 "utils.h"
33 #include "vblank.h"
34 #include "xmlpool.h"
35
36 #include "dri_screen.h"
37 #include "dri_context.h"
38 #include "dri_drawable.h"
39
40 #include "pipe/p_context.h"
41 #include "pipe/p_screen.h"
42 #include "pipe/p_inlines.h"
43 #include "pipe/p_format.h"
44 #include "state_tracker/drm_api.h"
45 #include "state_tracker/dri1_api.h"
46 #include "state_tracker/st_public.h"
47 #include "state_tracker/st_cb_fbo.h"
48
49
50 PUBLIC const char __driConfigOptions[] =
51 DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE
52 DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
53 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
54 DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY
55 /*DRI_CONF_FORCE_S3TC_ENABLE(false)*/
56 DRI_CONF_ALLOW_LARGE_TEXTURES(1)
57 DRI_CONF_SECTION_END DRI_CONF_END;
58
59
60 const uint __driNConfigOptions = 3;
61
62 static const __DRIextension *dri_screen_extensions[] = {
63 &driReadDrawableExtension,
64 &driCopySubBufferExtension.base,
65 &driSwapControlExtension.base,
66 &driFrameTrackingExtension.base,
67 &driMediaStreamCounterExtension.base,
68 NULL
69 };
70
71 struct dri1_api *__dri1_api_hooks = NULL;
72
73 static const __DRIconfig **
74 dri_fill_in_modes(__DRIscreenPrivate *psp,
75 unsigned pixel_bits, unsigned depth_bits,
76 unsigned stencil_bits, GLboolean have_back_buffer)
77 {
78 __DRIconfig **configs;
79 __GLcontextModes *m;
80 unsigned num_modes;
81 uint8_t depth_bits_array[3];
82 uint8_t stencil_bits_array[3];
83 uint8_t msaa_samples_array[1];
84 unsigned depth_buffer_factor;
85 unsigned back_buffer_factor;
86 unsigned msaa_samples_factor;
87 GLenum fb_format;
88 GLenum fb_type;
89 int i;
90
91 static const GLenum back_buffer_modes[] = {
92 GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
93 };
94
95 /* TODO probe the hardware of what is supports */
96 depth_bits_array[0] = 0;
97 depth_bits_array[1] = 24;
98 depth_bits_array[2] = 24;
99
100 stencil_bits_array[0] = 0; /* no depth or stencil */
101 stencil_bits_array[1] = 0; /* z24x8 */
102 stencil_bits_array[2] = 8; /* z24s8 */
103
104 msaa_samples_array[0] = 0;
105
106 depth_buffer_factor = 3;
107 back_buffer_factor = 3;
108 msaa_samples_factor = 1;
109
110 num_modes = depth_buffer_factor * back_buffer_factor * msaa_samples_factor * 4;
111
112 if (pixel_bits == 16) {
113 fb_format = GL_RGB;
114 fb_type = GL_UNSIGNED_SHORT_5_6_5;
115 }
116 else {
117 fb_format = GL_BGRA;
118 fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
119 }
120
121 configs = driCreateConfigs(fb_format, fb_type,
122 depth_bits_array,
123 stencil_bits_array, depth_buffer_factor,
124 back_buffer_modes, back_buffer_factor,
125 msaa_samples_array, msaa_samples_factor);
126 if (configs == NULL) {
127 debug_printf("%s: driCreateConfigs failed\n", __FUNCTION__);
128 return NULL;
129 }
130
131 for (i = 0; configs[i]; i++) {
132 m = &configs[i]->modes;
133 if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) {
134 m->visualRating = GLX_SLOW_CONFIG;
135 }
136 }
137
138 return (const const __DRIconfig **) configs;
139 }
140
141
142 /**
143 * Get information about previous buffer swaps.
144 */
145 static int
146 dri_get_swap_info(__DRIdrawablePrivate * dPriv,
147 __DRIswapInfo * sInfo)
148 {
149 if (dPriv == NULL ||
150 dPriv->driverPrivate == NULL ||
151 sInfo == NULL)
152 return -1;
153 else
154 return 0;
155 }
156
157 static INLINE void
158 dri_copy_version(struct dri1_api_version *dst,
159 const struct __DRIversionRec *src)
160 {
161 dst->major = src->major;
162 dst->minor = src->minor;
163 dst->patch_level = src->patch;
164 }
165
166 static const __DRIconfig **
167 dri_init_screen(__DRIscreenPrivate *sPriv)
168 {
169 struct dri_screen *screen;
170 const __DRIconfig **configs;
171 struct dri1_create_screen_arg arg;
172
173 dri_init_extensions(NULL);
174
175 screen = CALLOC_STRUCT(dri_screen);
176 if (!screen)
177 return NULL;
178
179 screen->sPriv = sPriv;
180 screen->fd = sPriv->fd;
181 screen->drmLock = (drmLock *) &sPriv->pSAREA->lock;
182
183 sPriv->private = (void *) screen;
184 sPriv->extensions = dri_screen_extensions;
185
186 arg.base.mode = DRM_CREATE_DRI1;
187 arg.lf = &dri1_lf;
188 arg.ddx_info = sPriv->pDevPriv;
189 arg.ddx_info_size = sPriv->devPrivSize;
190 arg.sarea = sPriv->pSAREA;
191 dri_copy_version(&arg.ddx_version, &sPriv->ddx_version);
192 dri_copy_version(&arg.dri_version, &sPriv->dri_version);
193 dri_copy_version(&arg.drm_version, &sPriv->drm_version);
194 arg.api = NULL;
195
196 screen->pipe_screen = drm_api_hooks.create_screen
197 (screen->fd, &arg.base);
198
199 if (!screen->pipe_screen || !arg.api) {
200 debug_printf("%s: failed to create dri1 screen\n", __FUNCTION__);
201 goto out_no_screen;
202 }
203
204 __dri1_api_hooks = arg.api;
205
206 screen->pipe_screen->flush_frontbuffer = dri1_flush_frontbuffer;
207 driParseOptionInfo(&screen->optionCache,
208 __driConfigOptions,
209 __driNConfigOptions);
210
211 configs = dri_fill_in_modes(sPriv, sPriv->fbBPP, 24, 8, 1);
212 if (!configs)
213 goto out_no_configs;
214
215 return configs;
216 out_no_configs:
217 screen->pipe_screen->destroy(screen->pipe_screen);
218 out_no_screen:
219 FREE(screen);
220 return NULL;
221 }
222
223
224 /**
225 * This is the driver specific part of the createNewScreen entry point.
226 *
227 * Returns the __GLcontextModes supported by this driver.
228 */
229 static const __DRIconfig **
230 dri_init_screen2(__DRIscreenPrivate *sPriv)
231 {
232 struct dri_screen *screen;
233 struct drm_create_screen_arg arg;
234
235 /* Set up dispatch table to cope with all known extensions */
236 dri_init_extensions(NULL);
237
238 screen = CALLOC_STRUCT(dri_screen);
239 if (!screen)
240 goto fail;
241
242 screen->sPriv = sPriv;
243 screen->fd = sPriv->fd;
244 sPriv->private = (void *) screen;
245 sPriv->extensions = dri_screen_extensions;
246 arg.mode = DRM_CREATE_NORMAL;
247
248 screen->pipe_screen = drm_api_hooks.create_screen(screen->fd, &arg);
249 if (!screen->pipe_screen) {
250 debug_printf("%s: failed to create pipe_screen\n", __FUNCTION__);
251 goto fail;
252 }
253
254 /* We need to hook in here */
255 screen->pipe_screen->flush_frontbuffer = dri_flush_frontbuffer;
256
257 driParseOptionInfo(&screen->optionCache,
258 __driConfigOptions,
259 __driNConfigOptions);
260
261 return dri_fill_in_modes(sPriv,
262 4 * 8,
263 24,
264 8,
265 1);
266 fail:
267 return NULL;
268 }
269
270
271 static void
272 dri_destroy_screen(__DRIscreenPrivate * sPriv)
273 {
274 struct dri_screen *screen = dri_screen(sPriv);
275
276 screen->pipe_screen->destroy(screen->pipe_screen);
277 FREE(screen);
278 sPriv->private = NULL;
279 }
280
281
282 PUBLIC const struct __DriverAPIRec driDriverAPI = {
283 .InitScreen = dri_init_screen,
284 .DestroyScreen = dri_destroy_screen,
285 .CreateContext = dri_create_context,
286 .DestroyContext = dri_destroy_context,
287 .CreateBuffer = dri_create_buffer,
288 .DestroyBuffer = dri_destroy_buffer,
289 .SwapBuffers = dri_swap_buffers,
290 .MakeCurrent = dri_make_current,
291 .UnbindContext = dri_unbind_context,
292 .GetSwapInfo = dri_get_swap_info,
293 .GetDrawableMSC = driDrawableGetMSC32,
294 .WaitForMSC = driWaitForMSC32,
295 .CopySubBuffer = dri_copy_sub_buffer,
296 .InitScreen = dri_init_screen,
297 .InitScreen2 = dri_init_screen2,
298 };
299
300 /* vim: set sw=3 ts=8 sts=3 expandtab: */