1 /**************************************************************************
3 * Copyright 2009, VMware, Inc.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
28 * Author: Keith Whitwell <keithw@vmware.com>
29 * Author: Jakob Bornecrantz <wallbraker@gmail.com>
36 #include "dri_screen.h"
37 #include "dri_context.h"
38 #include "dri_drawable.h"
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"
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
;
60 const uint __driNConfigOptions
= 3;
62 static const __DRIextension
*dri_screen_extensions
[] = {
63 &driReadDrawableExtension
,
64 &driCopySubBufferExtension
.base
,
65 &driSwapControlExtension
.base
,
66 &driFrameTrackingExtension
.base
,
67 &driMediaStreamCounterExtension
.base
,
71 struct dri1_api
*__dri1_api_hooks
= NULL
;
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
)
78 __DRIconfig
**configs
;
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
;
91 static const GLenum back_buffer_modes
[] = {
92 GLX_NONE
, GLX_SWAP_UNDEFINED_OML
, GLX_SWAP_COPY_OML
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;
100 stencil_bits_array
[0] = 0; /* no depth or stencil */
101 stencil_bits_array
[1] = 0; /* z24x8 */
102 stencil_bits_array
[2] = 8; /* z24s8 */
104 msaa_samples_array
[0] = 0;
106 depth_buffer_factor
= 3;
107 back_buffer_factor
= 3;
108 msaa_samples_factor
= 1;
110 num_modes
= depth_buffer_factor
* back_buffer_factor
* msaa_samples_factor
* 4;
112 if (pixel_bits
== 16) {
114 fb_type
= GL_UNSIGNED_SHORT_5_6_5
;
118 fb_type
= GL_UNSIGNED_INT_8_8_8_8_REV
;
121 configs
= driCreateConfigs(fb_format
, fb_type
,
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__
);
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
;
138 return (const const __DRIconfig
**) configs
;
143 * Get information about previous buffer swaps.
146 dri_get_swap_info(__DRIdrawablePrivate
* dPriv
,
147 __DRIswapInfo
* sInfo
)
150 dPriv
->driverPrivate
== NULL
||
158 dri_copy_version(struct dri1_api_version
*dst
,
159 const struct __DRIversionRec
*src
)
161 dst
->major
= src
->major
;
162 dst
->minor
= src
->minor
;
163 dst
->patch_level
= src
->patch
;
166 static const __DRIconfig
**
167 dri_init_screen(__DRIscreenPrivate
*sPriv
)
169 struct dri_screen
*screen
;
170 const __DRIconfig
**configs
;
171 struct dri1_create_screen_arg arg
;
173 dri_init_extensions(NULL
);
175 screen
= CALLOC_STRUCT(dri_screen
);
179 screen
->sPriv
= sPriv
;
180 screen
->fd
= sPriv
->fd
;
181 screen
->drmLock
= (drmLock
*) &sPriv
->pSAREA
->lock
;
183 sPriv
->private = (void *) screen
;
184 sPriv
->extensions
= dri_screen_extensions
;
186 arg
.base
.mode
= DRM_CREATE_DRI1
;
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
);
196 screen
->pipe_screen
= drm_api_hooks
.create_screen
197 (screen
->fd
, &arg
.base
);
199 if (!screen
->pipe_screen
|| !arg
.api
) {
200 debug_printf("%s: failed to create dri1 screen\n", __FUNCTION__
);
204 __dri1_api_hooks
= arg
.api
;
206 screen
->pipe_screen
->flush_frontbuffer
= dri1_flush_frontbuffer
;
207 driParseOptionInfo(&screen
->optionCache
,
209 __driNConfigOptions
);
211 configs
= dri_fill_in_modes(sPriv
, sPriv
->fbBPP
, 24, 8, 1);
217 screen
->pipe_screen
->destroy(screen
->pipe_screen
);
225 * This is the driver specific part of the createNewScreen entry point.
227 * Returns the __GLcontextModes supported by this driver.
229 static const __DRIconfig
**
230 dri_init_screen2(__DRIscreenPrivate
*sPriv
)
232 struct dri_screen
*screen
;
233 struct drm_create_screen_arg arg
;
235 /* Set up dispatch table to cope with all known extensions */
236 dri_init_extensions(NULL
);
238 screen
= CALLOC_STRUCT(dri_screen
);
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
;
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__
);
254 /* We need to hook in here */
255 screen
->pipe_screen
->flush_frontbuffer
= dri_flush_frontbuffer
;
257 driParseOptionInfo(&screen
->optionCache
,
259 __driNConfigOptions
);
261 return dri_fill_in_modes(sPriv
,
272 dri_destroy_screen(__DRIscreenPrivate
* sPriv
)
274 struct dri_screen
*screen
= dri_screen(sPriv
);
276 screen
->pipe_screen
->destroy(screen
->pipe_screen
);
278 sPriv
->private = NULL
;
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
,
300 /* vim: set sw=3 ts=8 sts=3 expandtab: */