2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
32 #include "simple_list.h"
34 #include "via_state.h"
38 #include "via_ioctl.h"
39 #include "via_screen.h"
43 extern viaContextPtr current_mesa
;
45 #ifdef USE_NEW_INTERFACE
46 static PFNGLXCREATECONTEXTMODES create_context_modes
= NULL
;
47 #endif /* USE_NEW_INTERFACE */
50 static drmBufMapPtr
via_create_empty_buffers(void)
54 retval
= (drmBufMapPtr
)MALLOC(sizeof(drmBufMap
));
55 if (retval
== NULL
) return NULL
;
56 memset(retval
, 0, sizeof(drmBufMap
));
58 retval
->list
= (drmBufPtr
)MALLOC(sizeof(drmBuf
) * VIA_DMA_BUF_NR
);
59 if (retval
->list
== NULL
) {
63 memset(retval
->list
, 0, sizeof(drmBuf
) * VIA_DMA_BUF_NR
);
68 viaInitDriver(__DRIscreenPrivate
*sPriv
)
70 viaScreenPrivate
*viaScreen
;
71 VIADRIPtr gDRIPriv
= (VIADRIPtr
)sPriv
->pDevPriv
;
73 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
77 /* Allocate the private area */
78 viaScreen
= (viaScreenPrivate
*) CALLOC(sizeof(viaScreenPrivate
));
80 __driUtilMessage("viaInitDriver: alloc viaScreenPrivate struct failed");
84 viaScreen
->driScrnPriv
= sPriv
;
85 sPriv
->private = (void *)viaScreen
;
87 viaScreen
->deviceID
= gDRIPriv
->deviceID
;
88 viaScreen
->width
= gDRIPriv
->width
;
89 viaScreen
->height
= gDRIPriv
->height
;
90 viaScreen
->mem
= gDRIPriv
->mem
;
91 viaScreen
->bitsPerPixel
= gDRIPriv
->bytesPerPixel
<< 3;
92 viaScreen
->bytesPerPixel
= gDRIPriv
->bytesPerPixel
;
93 viaScreen
->fbOffset
= 0;
94 viaScreen
->fbSize
= gDRIPriv
->fbSize
;
96 viaScreen
->drixinerama
= gDRIPriv
->drixinerama
;
98 /*=* John Sheng [2003.12.9] Tuxracer & VQ *=*/
99 viaScreen
->VQEnable
= gDRIPriv
->VQEnable
;
102 fprintf(stderr
, "deviceID = %08x\n", viaScreen
->deviceID
);
103 fprintf(stderr
, "width = %08x\n", viaScreen
->width
);
104 fprintf(stderr
, "height = %08x\n", viaScreen
->height
);
105 fprintf(stderr
, "cpp = %08x\n", viaScreen
->cpp
);
106 fprintf(stderr
, "fbOffset = %08x\n", viaScreen
->fbOffset
);
111 if (gDRIPriv->bitsPerPixel == 15)
112 viaScreen->fbFormat = DV_PF_555;
114 viaScreen->fbFormat = DV_PF_565;
117 viaScreen
->bufs
= via_create_empty_buffers();
118 if (viaScreen
->bufs
== NULL
) {
119 __driUtilMessage("viaInitDriver: via_create_empty_buffers() failed");
124 if (drmMap(sPriv
->fd
,
125 gDRIPriv
->regs
.handle
,
127 (drmAddress
*)&viaScreen
->reg
) != 0) {
129 sPriv
->private = NULL
;
130 __driUtilMessage("viaInitDriver: drmMap regs failed");
134 if (gDRIPriv
->agp
.size
) {
135 if (drmMap(sPriv
->fd
,
136 gDRIPriv
->agp
.handle
,
138 (drmAddress
*)&viaScreen
->agpLinearStart
) != 0) {
140 drmUnmap(viaScreen
->reg
, gDRIPriv
->agp
.size
);
141 sPriv
->private = NULL
;
142 __driUtilMessage("viaInitDriver: drmMap agp failed");
145 viaScreen
->agpBase
= (GLuint
*)gDRIPriv
->agp
.handle
;
147 viaScreen
->agpLinearStart
= 0;
149 viaScreen
->sareaPrivOffset
= gDRIPriv
->sarea_priv_offset
;
151 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
157 viaDestroyScreen(__DRIscreenPrivate
*sPriv
)
159 viaScreenPrivate
*viaScreen
= (viaScreenPrivate
*)sPriv
->private;
160 VIADRIPtr gDRIPriv
= (VIADRIPtr
)sPriv
->pDevPriv
;
162 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
164 drmUnmap(viaScreen
->reg
, gDRIPriv
->regs
.size
);
165 if (gDRIPriv
->agp
.size
)
166 drmUnmap(viaScreen
->agpLinearStart
, gDRIPriv
->agp
.size
);
168 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
171 sPriv
->private = NULL
;
175 viaCreateBuffer(__DRIscreenPrivate
*driScrnPriv
,
176 __DRIdrawablePrivate
*driDrawPriv
,
177 const __GLcontextModes
*mesaVis
,
180 viaContextPtr vmesa
= current_mesa
;
182 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
184 /*=* John Sheng [2003.7.2] for visual config & patch viewperf *=*/
185 if (mesaVis
->depthBits
== 32 && vmesa
->depthBits
== 16) {
186 vmesa
->depthBits
= mesaVis
->depthBits
;
187 vmesa
->depth
.size
*= 2;
188 vmesa
->depth
.pitch
*= 2;
189 vmesa
->depth
.bpp
*= 2;
190 if (vmesa
->depth
.map
)
191 via_free_depth_buffer(vmesa
);
192 if (!via_alloc_depth_buffer(vmesa
)) {
193 via_free_depth_buffer(vmesa
);
197 ((__GLcontextModes
*)mesaVis
)->depthBits
= 16; /* XXX : sure you want to change read-only data? */
201 driDrawPriv
->driverPrivate
= (void *)
202 _mesa_create_framebuffer(mesaVis
,
203 GL_FALSE
, /* software depth buffer? */
204 mesaVis
->stencilBits
> 0,
205 mesaVis
->accumRedBits
> 0,
206 GL_FALSE
/* s/w alpha planes */);
208 if (vmesa
) vmesa
->drawType
= GLX_PBUFFER_BIT
;
210 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
212 return (driDrawPriv
->driverPrivate
!= NULL
);
215 driDrawPriv
->driverPrivate
= (void *)
216 _mesa_create_framebuffer(mesaVis
,
217 GL_FALSE
, /* software depth buffer? */
218 mesaVis
->stencilBits
> 0,
219 mesaVis
->accumRedBits
> 0,
220 GL_FALSE
/* s/w alpha planes */);
222 if (vmesa
) vmesa
->drawType
= GLX_WINDOW_BIT
;
224 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
226 return (driDrawPriv
->driverPrivate
!= NULL
);
232 viaDestroyBuffer(__DRIdrawablePrivate
*driDrawPriv
)
235 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
237 _mesa_destroy_framebuffer((GLframebuffer
*)(driDrawPriv
->driverPrivate
));
239 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
245 /* Initialize the fullscreen mode.
248 XMesaOpenFullScreen(__DRIcontextPrivate
*driContextPriv
)
250 viaContextPtr vmesa
= (viaContextPtr
)driContextPriv
->driverPrivate
;
251 vmesa
->doPageFlip
= 1;
252 vmesa
->currentPage
= 0;
256 /* Shut down the fullscreen mode.
259 XMesaCloseFullScreen(__DRIcontextPrivate
*driContextPriv
)
261 viaContextPtr vmesa
= (viaContextPtr
)driContextPriv
->driverPrivate
;
263 if (vmesa
->currentPage
== 1) {
265 vmesa
->currentPage
= 0;
268 vmesa
->doPageFlip
= GL_FALSE
;
269 vmesa
->Setup
[VIA_DESTREG_DI0
] = vmesa
->driScreen
->front_offset
;
275 static struct __DriverAPIRec viaAPI
= {
289 * This is the bootstrap function for the driver.
290 * The __driCreateScreen name is the symbol that libGL.so fetches.
291 * Return: pointer to a __DRIscreenPrivate.
293 #if !defined(DRI_NEW_INTERFACE_ONLY)
294 void *__driCreateScreen(Display
*dpy
, int scrn
, __DRIscreen
*psc
,
295 int numConfigs
, __GLXvisualConfig
*config
)
297 __DRIscreenPrivate
*psp
;
298 psp
= __driUtilCreateScreen(dpy
, scrn
, psc
, numConfigs
, config
, &viaAPI
);
301 #endif /* !defined(DRI_NEW_INTERFACE_ONLY) */
304 #ifdef USE_NEW_INTERFACE
305 static __GLcontextModes
*
306 viaFillInModes( unsigned pixel_bits
, GLboolean have_back_buffer
)
308 __GLcontextModes
* modes
;
309 __GLcontextModes
* m
;
311 const unsigned back_buffer_factor
= (have_back_buffer
) ? 2 : 1;
315 /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
316 * enough to add support. Basically, if a context is created with an
317 * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
318 * will never be used.
320 static const GLenum back_buffer_modes
[] = {
321 GLX_NONE
, GLX_SWAP_UNDEFINED_OML
/*, GLX_SWAP_COPY_OML */
324 /* The 32-bit depth-buffer mode isn't supported yet, so don't actually
327 static const uint8_t depth_bits_array
[4] = { 0, 16, 24, 32 };
328 static const uint8_t stencil_bits_array
[4] = { 0, 0, 8, 0 };
329 const unsigned depth_buffer_factor
= 3;
332 num_modes
= depth_buffer_factor
* back_buffer_factor
* 4;
334 if ( pixel_bits
== 16 ) {
336 fb_type
= GL_UNSIGNED_SHORT_5_6_5
;
340 fb_type
= GL_UNSIGNED_INT_8_8_8_8_REV
;
343 modes
= (*create_context_modes
)( num_modes
, sizeof( __GLcontextModes
) );
345 if ( ! driFillInModes( & m
, fb_format
, fb_type
,
346 depth_bits_array
, stencil_bits_array
, depth_buffer_factor
,
347 back_buffer_modes
, back_buffer_factor
,
349 fprintf( stderr
, "[%s:%u] Error creating FBConfig!\n",
350 __func__
, __LINE__
);
354 if ( ! driFillInModes( & m
, fb_format
, fb_type
,
355 depth_bits_array
, stencil_bits_array
, depth_buffer_factor
,
356 back_buffer_modes
, back_buffer_factor
,
357 GLX_DIRECT_COLOR
) ) {
358 fprintf( stderr
, "[%s:%u] Error creating FBConfig!\n",
359 __func__
, __LINE__
);
365 #endif /* USE_NEW_INTERFACE */
369 * This is the bootstrap function for the driver. libGL supplies all of the
370 * requisite information about the system, and the driver initializes itself.
371 * This routine also fills in the linked list pointed to by \c driver_modes
372 * with the \c __GLcontextModes that the driver can support for windows or
375 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
378 #ifdef USE_NEW_INTERFACE
379 void * __driCreateNewScreen( __DRInativeDisplay
*dpy
, int scrn
, __DRIscreen
*psc
,
380 const __GLcontextModes
* modes
,
381 const __DRIversion
* ddx_version
,
382 const __DRIversion
* dri_version
,
383 const __DRIversion
* drm_version
,
384 const __DRIframebuffer
* frame_buffer
,
385 drmAddress pSAREA
, int fd
,
386 int internal_api_version
,
387 __GLcontextModes
** driver_modes
)
390 __DRIscreenPrivate
*psp
;
391 static const __DRIversion ddx_expected
= { 4, 0, 0 };
392 static const __DRIversion dri_expected
= { 4, 0, 0 };
393 static const __DRIversion drm_expected
= { 1, 1, 0 };
395 if ( ! driCheckDriDdxDrmVersions2( "Unichrome",
396 dri_version
, & dri_expected
,
397 ddx_version
, & ddx_expected
,
398 drm_version
, & drm_expected
) ) {
402 psp
= __driUtilCreateNewScreen(dpy
, scrn
, psc
, NULL
,
403 ddx_version
, dri_version
, drm_version
,
404 frame_buffer
, pSAREA
, fd
,
405 internal_api_version
, &viaAPI
);
407 create_context_modes
= (PFNGLXCREATECONTEXTMODES
)
408 glXGetProcAddress( (const GLubyte
*) "__glXCreateContextModes" );
409 if ( create_context_modes
!= NULL
) {
410 VIADRIPtr dri_priv
= (VIADRIPtr
) psp
->pDevPriv
;
411 *driver_modes
= viaFillInModes( dri_priv
->bytesPerPixel
* 8,
418 #endif /* USE_NEW_INTERFACE */