1 /* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_xmesa.c,v 1.4 2002/02/22 21:32:59 dawes Exp $
3 * GLX Hardware Device Driver for Sun Creator/Creator3D
4 * Copyright (C) 2000, 2001 David S. Miller
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * DAVID MILLER, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
22 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 * David S. Miller <davem@redhat.com>
28 #include "ffb_xmesa.h"
30 #include "framebuffer.h"
32 #include "renderbuffer.h"
33 #include "simple_list.h"
37 #include "swrast/swrast.h"
38 #include "swrast_setup/swrast_setup.h"
40 #include "tnl/t_pipeline.h"
41 #include "array_cache/acache.h"
42 #include "drivers/common/driverfuncs.h"
44 #include "ffb_context.h"
47 #include "ffb_depth.h"
48 #include "ffb_stencil.h"
49 #include "ffb_clear.h"
52 #include "ffb_lines.h"
53 #include "ffb_points.h"
54 #include "ffb_state.h"
57 #include "ffb_vtxfmt.h"
58 #include "ffb_bitmap.h"
60 #include "drm_sarea.h"
63 ffbInitDriver(__DRIscreenPrivate
*sPriv
)
65 ffbScreenPrivate
*ffbScreen
;
66 FFBDRIPtr gDRIPriv
= (FFBDRIPtr
) sPriv
->pDevPriv
;
68 if (getenv("LIBGL_FORCE_XSERVER"))
71 /* Allocate the private area. */
72 ffbScreen
= (ffbScreenPrivate
*) MALLOC(sizeof(ffbScreenPrivate
));
76 /* Map FBC registers. */
80 &gDRIPriv
->mFbcRegs
)) {
84 ffbScreen
->regs
= (ffb_fbcPtr
) gDRIPriv
->mFbcRegs
;
86 /* Map ramdac registers. */
90 &gDRIPriv
->mDacRegs
)) {
91 drmUnmap(gDRIPriv
->mFbcRegs
, gDRIPriv
->sFbcRegs
);
95 ffbScreen
->dac
= (ffb_dacPtr
) gDRIPriv
->mDacRegs
;
97 /* Map "Smart" framebuffer views. */
101 &gDRIPriv
->mSfb8r
)) {
102 drmUnmap(gDRIPriv
->mFbcRegs
, gDRIPriv
->sFbcRegs
);
103 drmUnmap(gDRIPriv
->mDacRegs
, gDRIPriv
->sDacRegs
);
107 ffbScreen
->sfb8r
= (volatile char *) gDRIPriv
->mSfb8r
;
109 if (drmMap(sPriv
->fd
,
112 &gDRIPriv
->mSfb32
)) {
113 drmUnmap(gDRIPriv
->mFbcRegs
, gDRIPriv
->sFbcRegs
);
114 drmUnmap(gDRIPriv
->mDacRegs
, gDRIPriv
->sDacRegs
);
115 drmUnmap(gDRIPriv
->mSfb8r
, gDRIPriv
->sSfb8r
);
119 ffbScreen
->sfb32
= (volatile char *) gDRIPriv
->mSfb32
;
121 if (drmMap(sPriv
->fd
,
124 &gDRIPriv
->mSfb64
)) {
125 drmUnmap(gDRIPriv
->mFbcRegs
, gDRIPriv
->sFbcRegs
);
126 drmUnmap(gDRIPriv
->mDacRegs
, gDRIPriv
->sDacRegs
);
127 drmUnmap(gDRIPriv
->mSfb8r
, gDRIPriv
->sSfb8r
);
128 drmUnmap(gDRIPriv
->mSfb32
, gDRIPriv
->sSfb32
);
132 ffbScreen
->sfb64
= (volatile char *) gDRIPriv
->mSfb64
;
134 ffbScreen
->fifo_cache
= 0;
135 ffbScreen
->rp_active
= 0;
137 ffbScreen
->sPriv
= sPriv
;
138 sPriv
->private = (void *) ffbScreen
;
141 ffbDDPointfuncInit();
148 ffbDestroyScreen(__DRIscreenPrivate
*sPriv
)
150 ffbScreenPrivate
*ffbScreen
= sPriv
->private;
151 FFBDRIPtr gDRIPriv
= (FFBDRIPtr
) sPriv
->pDevPriv
;
153 drmUnmap(gDRIPriv
->mFbcRegs
, gDRIPriv
->sFbcRegs
);
154 drmUnmap(gDRIPriv
->mDacRegs
, gDRIPriv
->sDacRegs
);
155 drmUnmap(gDRIPriv
->mSfb8r
, gDRIPriv
->sSfb8r
);
156 drmUnmap(gDRIPriv
->mSfb32
, gDRIPriv
->sSfb32
);
157 drmUnmap(gDRIPriv
->mSfb64
, gDRIPriv
->sSfb64
);
162 static const struct tnl_pipeline_stage
*ffb_pipeline
[] = {
163 &_tnl_vertex_transform_stage
,
164 &_tnl_normal_transform_stage
,
165 &_tnl_lighting_stage
,
166 /* REMOVE: fog coord stage */
168 &_tnl_texture_transform_stage
,
169 /* REMOVE: point attenuation stage */
174 /* Create and initialize the Mesa and driver specific context data */
176 ffbCreateContext(const __GLcontextModes
*mesaVis
,
177 __DRIcontextPrivate
*driContextPriv
,
178 void *sharedContextPrivate
)
181 GLcontext
*ctx
, *shareCtx
;
182 __DRIscreenPrivate
*sPriv
;
183 ffbScreenPrivate
*ffbScreen
;
185 struct dd_function_table functions
;
187 /* Allocate ffb context */
188 fmesa
= (ffbContextPtr
) CALLOC(sizeof(ffbContextRec
));
192 _mesa_init_driver_functions(&functions
);
194 /* Allocate Mesa context */
195 if (sharedContextPrivate
)
196 shareCtx
= ((ffbContextPtr
) sharedContextPrivate
)->glCtx
;
199 fmesa
->glCtx
= _mesa_create_context(mesaVis
, shareCtx
,
205 driContextPriv
->driverPrivate
= fmesa
;
208 sPriv
= driContextPriv
->driScreenPriv
;
209 ffbScreen
= (ffbScreenPrivate
*) sPriv
->private;
212 fmesa
->hHWContext
= driContextPriv
->hHWContext
;
213 fmesa
->driFd
= sPriv
->fd
;
214 fmesa
->driHwLock
= &sPriv
->pSAREA
->lock
;
216 fmesa
->ffbScreen
= ffbScreen
;
217 fmesa
->driScreen
= sPriv
;
218 fmesa
->ffb_sarea
= FFB_DRISHARE(sPriv
->pSAREA
);
220 /* Register and framebuffer hw pointers. */
221 fmesa
->regs
= ffbScreen
->regs
;
222 fmesa
->sfb32
= ffbScreen
->sfb32
;
224 ffbDDInitContextHwState(ctx
);
226 /* Default clear and depth colors. */
228 GLubyte r
= (GLint
) (ctx
->Color
.ClearColor
[0] * 255.0F
);
229 GLubyte g
= (GLint
) (ctx
->Color
.ClearColor
[1] * 255.0F
);
230 GLubyte b
= (GLint
) (ctx
->Color
.ClearColor
[2] * 255.0F
);
232 fmesa
->clear_pixel
= ((r
<< 0) |
236 fmesa
->clear_depth
= Z_FROM_MESA(ctx
->Depth
.Clear
* 4294967295.0f
);
237 fmesa
->clear_stencil
= ctx
->Stencil
.Clear
& 0xf;
239 /* No wide points. */
240 ctx
->Const
.MinPointSize
= 1.0;
241 ctx
->Const
.MinPointSizeAA
= 1.0;
242 ctx
->Const
.MaxPointSize
= 1.0;
243 ctx
->Const
.MaxPointSizeAA
= 1.0;
245 /* Disable wide lines as we can't antialias them correctly in
248 ctx
->Const
.MinLineWidth
= 1.0;
249 ctx
->Const
.MinLineWidthAA
= 1.0;
250 ctx
->Const
.MaxLineWidth
= 1.0;
251 ctx
->Const
.MaxLineWidthAA
= 1.0;
252 ctx
->Const
.LineWidthGranularity
= 1.0;
254 /* Instead of having GCC emit these constants a zillion times
255 * everywhere in the driver, put them here.
257 fmesa
->ffb_2_30_fixed_scale
= __FFB_2_30_FIXED_SCALE
;
258 fmesa
->ffb_one_over_2_30_fixed_scale
= (1.0 / __FFB_2_30_FIXED_SCALE
);
259 fmesa
->ffb_16_16_fixed_scale
= __FFB_16_16_FIXED_SCALE
;
260 fmesa
->ffb_one_over_16_16_fixed_scale
= (1.0 / __FFB_16_16_FIXED_SCALE
);
261 fmesa
->ffb_ubyte_color_scale
= 255.0f
;
262 fmesa
->ffb_zero
= 0.0f
;
264 fmesa
->debugFallbacks
= GL_FALSE
;
265 debug
= getenv("LIBGL_DEBUG");
266 if (debug
&& strstr(debug
, "fallbacks"))
267 fmesa
->debugFallbacks
= GL_TRUE
;
269 /* Initialize the software rasterizer and helper modules. */
270 _swrast_CreateContext( ctx
);
271 _ac_CreateContext( ctx
);
272 _tnl_CreateContext( ctx
);
273 _swsetup_CreateContext( ctx
);
275 /* All of this need only be done once for a new context. */
276 /* XXX these should be moved right after the
277 * _mesa_init_driver_functions() call above.
279 ffbDDExtensionsInit(ctx
);
280 ffbDDInitDriverFuncs(ctx
);
281 ffbDDInitStateFuncs(ctx
);
282 ffbDDInitRenderFuncs(ctx
);
283 /*ffbDDInitTexFuncs(ctx); not needed */
284 ffbDDInitBitmapFuncs(ctx
);
288 ffbInitTnlModule(ctx
);
291 _tnl_destroy_pipeline(ctx
);
292 _tnl_install_pipeline(ctx
, ffb_pipeline
);
298 ffbDestroyContext(__DRIcontextPrivate
*driContextPriv
)
300 ffbContextPtr fmesa
= (ffbContextPtr
) driContextPriv
->driverPrivate
;
303 ffbFreeVB(fmesa
->glCtx
);
305 _swsetup_DestroyContext( fmesa
->glCtx
);
306 _tnl_DestroyContext( fmesa
->glCtx
);
307 _ac_DestroyContext( fmesa
->glCtx
);
308 _swrast_DestroyContext( fmesa
->glCtx
);
310 /* free the Mesa context */
311 fmesa
->glCtx
->DriverCtx
= NULL
;
312 _mesa_destroy_context(fmesa
->glCtx
);
318 /* Create and initialize the Mesa and driver specific pixmap buffer data */
320 ffbCreateBuffer(__DRIscreenPrivate
*driScrnPriv
,
321 __DRIdrawablePrivate
*driDrawPriv
,
322 const __GLcontextModes
*mesaVis
,
325 /* Mesa checks for pitch > 0, but ffb doesn't use pitches */
327 int bpp
= 4; /* we've always got a 32bpp framebuffer */
328 int offset
= 0; /* always at 0 for offset */
331 return GL_FALSE
; /* not implemented */
333 GLboolean swStencil
= (mesaVis
->stencilBits
> 0 &&
334 mesaVis
->depthBits
!= 24);
336 driDrawPriv
->driverPrivate
= (void *)
337 _mesa_create_framebuffer(mesaVis
,
338 GL_FALSE
, /* software depth buffer? */
339 mesaVis
->stencilBits
> 0,
340 mesaVis
->accumRedBits
> 0,
341 mesaVis
->alphaBits
> 0);
343 struct gl_framebuffer
*fb
= _mesa_create_framebuffer(mesaVis
);
346 driRenderbuffer
*frontRb
347 = driNewRenderbuffer(GL_RGBA
, bpp
, offset
, bogusPitch
);
348 ffbSetSpanFunctions(frontRb
, mesaVis
);
349 _mesa_add_renderbuffer(fb
, BUFFER_FRONT_LEFT
, &frontRb
->Base
);
352 if (mesaVis
->doubleBufferMode
) {
353 driRenderbuffer
*backRb
354 = driNewRenderbuffer(GL_RGBA
, bpp
, offset
, bogusPitch
);
355 ffbSetSpanFunctions(backRb
, mesaVis
);
356 _mesa_add_renderbuffer(fb
, BUFFER_BACK_LEFT
, &backRb
->Base
);
359 if (mesaVis
->depthBits
== 16) {
360 driRenderbuffer
*depthRb
361 = driNewRenderbuffer(GL_DEPTH_COMPONENT16
, bpp
, offset
, bogusPitch
);
362 ffbSetDepthFunctions(depthRb
, mesaVis
);
363 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, &depthRb
->Base
);
366 if (mesaVis
->stencilBits
> 0 && !swStencil
) {
367 driRenderbuffer
*stencilRb
368 = driNewRenderbuffer(GL_STENCIL_INDEX8_EXT
, bpp
, offset
,bogusPitch
);
369 ffbSetStencilFunctions(stencilRb
, mesaVis
);
370 _mesa_add_renderbuffer(fb
, BUFFER_STENCIL
, &stencilRb
->Base
);
373 _mesa_add_soft_renderbuffers(fb
,
374 GL_FALSE
, /* color */
375 GL_FALSE
, /* depth */
377 mesaVis
->accumRedBits
> 0,
378 GL_FALSE
, /* alpha */
380 driDrawPriv
->driverPrivate
= (void *) fb
;
382 return (driDrawPriv
->driverPrivate
!= NULL
);
388 ffbDestroyBuffer(__DRIdrawablePrivate
*driDrawPriv
)
390 _mesa_destroy_framebuffer((GLframebuffer
*) (driDrawPriv
->driverPrivate
));
394 #define USE_FAST_SWAP
397 ffbSwapBuffers( __DRIdrawablePrivate
*dPriv
)
399 ffbContextPtr fmesa
= (ffbContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
400 unsigned int fbc
, wid
, wid_reg_val
, dac_db_bit
;
401 unsigned int shadow_dac_addr
, active_dac_addr
;
406 fmesa
->glCtx
->Visual
.doubleBufferMode
== 0)
409 /* Flush pending rendering commands */
410 _mesa_notifySwapBuffers(fmesa
->glCtx
);
413 dac
= fmesa
->ffbScreen
->dac
;
418 /* Swap the buffer we render into and read pixels from. */
419 fmesa
->back_buffer
^= 1;
421 /* If we are writing into both buffers, don't mess with
424 if ((fbc
& FFB_FBC_WB_AB
) != FFB_FBC_WB_AB
) {
425 if ((fbc
& FFB_FBC_WB_A
) != 0)
426 fbc
= (fbc
& ~FFB_FBC_WB_A
) | FFB_FBC_WB_B
;
428 fbc
= (fbc
& ~FFB_FBC_WB_B
) | FFB_FBC_WB_A
;
431 /* But either way, we must flip the read buffer setting. */
432 if ((fbc
& FFB_FBC_RB_A
) != 0)
433 fbc
= (fbc
& ~FFB_FBC_RB_A
) | FFB_FBC_RB_B
;
435 fbc
= (fbc
& ~FFB_FBC_RB_B
) | FFB_FBC_RB_A
;
437 LOCK_HARDWARE(fmesa
);
439 if (fmesa
->fbc
!= fbc
) {
441 ffb
->fbc
= fmesa
->fbc
= fbc
;
442 fmesa
->ffbScreen
->rp_active
= 1;
445 /* And swap the buffer displayed in the WID. */
446 if (fmesa
->ffb_sarea
->flags
& FFB_DRI_PAC1
) {
447 shadow_dac_addr
= FFBDAC_PAC1_SPWLUT(wid
);
448 active_dac_addr
= FFBDAC_PAC1_APWLUT(wid
);
449 dac_db_bit
= FFBDAC_PAC1_WLUT_DB
;
451 shadow_dac_addr
= FFBDAC_PAC2_SPWLUT(wid
);
452 active_dac_addr
= FFBDAC_PAC2_APWLUT(wid
);
453 dac_db_bit
= FFBDAC_PAC2_WLUT_DB
;
458 wid_reg_val
= DACCFG_READ(dac
, active_dac_addr
);
459 if (fmesa
->back_buffer
== 0)
460 wid_reg_val
|= dac_db_bit
;
462 wid_reg_val
&= ~dac_db_bit
;
464 DACCFG_WRITE(dac
, active_dac_addr
, wid_reg_val
);
466 DACCFG_WRITE(dac
, shadow_dac_addr
, wid_reg_val
);
468 /* Schedule the window transfer. */
469 DACCFG_WRITE(dac
, FFBDAC_CFG_WTCTRL
,
470 (FFBDAC_CFG_WTCTRL_TCMD
| FFBDAC_CFG_WTCTRL_TE
));
475 unsigned int wtctrl
= DACCFG_READ(dac
, FFBDAC_CFG_WTCTRL
);
477 if ((wtctrl
& FFBDAC_CFG_WTCTRL_DS
) == 0)
483 UNLOCK_HARDWARE(fmesa
);
486 static void ffb_init_wid(ffbContextPtr fmesa
, unsigned int wid
)
488 ffb_dacPtr dac
= fmesa
->ffbScreen
->dac
;
489 unsigned int wid_reg_val
, dac_db_bit
, active_dac_addr
;
490 unsigned int shadow_dac_addr
;
492 if (fmesa
->ffb_sarea
->flags
& FFB_DRI_PAC1
) {
493 shadow_dac_addr
= FFBDAC_PAC1_SPWLUT(wid
);
494 active_dac_addr
= FFBDAC_PAC1_APWLUT(wid
);
495 dac_db_bit
= FFBDAC_PAC1_WLUT_DB
;
497 shadow_dac_addr
= FFBDAC_PAC2_SPWLUT(wid
);
498 active_dac_addr
= FFBDAC_PAC2_APWLUT(wid
);
499 dac_db_bit
= FFBDAC_PAC2_WLUT_DB
;
502 wid_reg_val
= DACCFG_READ(dac
, active_dac_addr
);
503 wid_reg_val
&= ~dac_db_bit
;
505 DACCFG_WRITE(dac
, active_dac_addr
, wid_reg_val
);
507 DACCFG_WRITE(dac
, shadow_dac_addr
, wid_reg_val
);
509 /* Schedule the window transfer. */
510 DACCFG_WRITE(dac
, FFBDAC_CFG_WTCTRL
,
511 (FFBDAC_CFG_WTCTRL_TCMD
| FFBDAC_CFG_WTCTRL_TE
));
516 unsigned int wtctrl
= DACCFG_READ(dac
, FFBDAC_CFG_WTCTRL
);
518 if ((wtctrl
& FFBDAC_CFG_WTCTRL_DS
) == 0)
525 /* Force the context `c' to be the current context and associate with it
528 ffbMakeCurrent(__DRIcontextPrivate
*driContextPriv
,
529 __DRIdrawablePrivate
*driDrawPriv
,
530 __DRIdrawablePrivate
*driReadPriv
)
532 if (driContextPriv
) {
533 ffbContextPtr fmesa
= (ffbContextPtr
) driContextPriv
->driverPrivate
;
536 fmesa
->driDrawable
= driDrawPriv
;
538 _mesa_make_current(fmesa
->glCtx
,
539 (GLframebuffer
*) driDrawPriv
->driverPrivate
,
540 (GLframebuffer
*) driReadPriv
->driverPrivate
);
543 if (fmesa
->wid
== ~0) {
545 if (getenv("LIBGL_SOFTWARE_RENDERING"))
546 FALLBACK( fmesa
->glCtx
, FFB_BADATTR_SWONLY
, GL_TRUE
);
549 LOCK_HARDWARE(fmesa
);
551 fmesa
->wid
= fmesa
->ffb_sarea
->wid_table
[driDrawPriv
->index
];
552 ffb_init_wid(fmesa
, fmesa
->wid
);
555 fmesa
->state_dirty
|= FFB_STATE_ALL
;
556 fmesa
->state_fifo_ents
= fmesa
->state_all_fifo_ents
;
557 ffbSyncHardware(fmesa
);
558 UNLOCK_HARDWARE(fmesa
);
561 /* Also, at the first switch to a new context,
562 * we need to clear all the hw buffers.
564 ffbDDClear(fmesa
->glCtx
,
565 (BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
|
566 BUFFER_BIT_DEPTH
| BUFFER_BIT_STENCIL
),
570 _mesa_make_current(NULL
, NULL
, NULL
);
576 /* Force the context `c' to be unbound from its buffer */
578 ffbUnbindContext(__DRIcontextPrivate
*driContextPriv
)
583 void ffbXMesaUpdateState(ffbContextPtr fmesa
)
585 __DRIdrawablePrivate
*dPriv
= fmesa
->driDrawable
;
586 __DRIscreenPrivate
*sPriv
= fmesa
->driScreen
;
587 int stamp
= dPriv
->lastStamp
;
589 DRI_VALIDATE_DRAWABLE_INFO(sPriv
, dPriv
);
591 if (dPriv
->lastStamp
!= stamp
) {
592 GLcontext
*ctx
= fmesa
->glCtx
;
594 ffbCalcViewport(ctx
);
595 if (ctx
->Polygon
.StippleFlag
)
596 ffbXformAreaPattern(fmesa
,
597 (const GLubyte
*)ctx
->PolygonStipple
);
601 static const struct __DriverAPIRec ffbAPI
= {
602 .InitDriver
= ffbInitDriver
,
603 .DestroyScreen
= ffbDestroyScreen
,
604 .CreateContext
= ffbCreateContext
,
605 .DestroyContext
= ffbDestroyContext
,
606 .CreateBuffer
= ffbCreateBuffer
,
607 .DestroyBuffer
= ffbDestroyBuffer
,
608 .SwapBuffers
= ffbSwapBuffers
,
609 .MakeCurrent
= ffbMakeCurrent
,
610 .UnbindContext
= ffbUnbindContext
,
615 .SwapBuffersMSC
= NULL
619 static PFNGLXCREATECONTEXTMODES create_context_modes
= NULL
;
621 static __GLcontextModes
*
622 ffbFillInModes( unsigned pixel_bits
, unsigned depth_bits
,
623 unsigned stencil_bits
, GLboolean have_back_buffer
)
625 __GLcontextModes
* modes
;
626 __GLcontextModes
* m
;
628 unsigned depth_buffer_factor
;
629 unsigned back_buffer_factor
;
633 /* GLX_SWAP_COPY_OML is only supported because the FFB driver doesn't
634 * support pageflipping at all.
636 static const GLenum back_buffer_modes
[] = {
637 GLX_NONE
, GLX_SWAP_UNDEFINED_OML
, GLX_SWAP_COPY_OML
640 u_int8_t depth_bits_array
[3];
641 u_int8_t stencil_bits_array
[3];
644 depth_bits_array
[0] = 0;
645 depth_bits_array
[1] = depth_bits
;
646 depth_bits_array
[2] = depth_bits
;
648 /* Just like with the accumulation buffer, always provide some modes
649 * with a stencil buffer. It will be a sw fallback, but some apps won't
652 stencil_bits_array
[0] = 0;
653 stencil_bits_array
[1] = 0;
654 stencil_bits_array
[2] = (stencil_bits
== 0) ? 8 : stencil_bits
;
656 depth_buffer_factor
= ((depth_bits
!= 0) || (stencil_bits
!= 0)) ? 3 : 1;
657 back_buffer_factor
= (have_back_buffer
) ? 3 : 1;
659 num_modes
= depth_buffer_factor
* back_buffer_factor
* 4;
661 if ( pixel_bits
== 16 ) {
663 fb_type
= GL_UNSIGNED_SHORT_5_6_5
;
667 fb_type
= GL_UNSIGNED_INT_8_8_8_8_REV
;
670 modes
= (*create_context_modes
)( num_modes
, sizeof( __GLcontextModes
) );
672 if ( ! driFillInModes( & m
, fb_format
, fb_type
,
673 depth_bits_array
, stencil_bits_array
, depth_buffer_factor
,
674 back_buffer_modes
, back_buffer_factor
,
676 fprintf( stderr
, "[%s:%u] Error creating FBConfig!\n",
677 __func__
, __LINE__
);
680 if ( ! driFillInModes( & m
, fb_format
, fb_type
,
681 depth_bits_array
, stencil_bits_array
, depth_buffer_factor
,
682 back_buffer_modes
, back_buffer_factor
,
683 GLX_DIRECT_COLOR
) ) {
684 fprintf( stderr
, "[%s:%u] Error creating FBConfig!\n",
685 __func__
, __LINE__
);
690 /* Mark the visual as slow if there are "fake" stencil bits.
692 for ( m
= modes
; m
!= NULL
; m
= m
->next
) {
693 if ( (m
->stencilBits
!= 0) && (m
->stencilBits
!= stencil_bits
) ) {
694 m
->visualRating
= GLX_SLOW_CONFIG
;
703 * This is the bootstrap function for the driver. libGL supplies all of the
704 * requisite information about the system, and the driver initializes itself.
705 * This routine also fills in the linked list pointed to by \c driver_modes
706 * with the \c __GLcontextModes that the driver can support for windows or
709 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
713 void * __driCreateNewScreen_20050722( __DRInativeDisplay
*dpy
, int scrn
, __DRIscreen
*psc
,
714 const __GLcontextModes
* modes
,
715 const __DRIversion
* ddx_version
,
716 const __DRIversion
* dri_version
,
717 const __DRIversion
* drm_version
,
718 const __DRIframebuffer
* frame_buffer
,
719 drmAddress pSAREA
, int fd
,
720 int internal_api_version
,
721 __GLcontextModes
** driver_modes
)
724 __DRIscreenPrivate
*psp
;
725 static const __DRIversion ddx_expected
= { 0, 0, 1 };
726 static const __DRIversion dri_expected
= { 4, 0, 0 };
727 static const __DRIversion drm_expected
= { 0, 0, 1 };
729 if ( ! driCheckDriDdxDrmVersions2( "ffb",
730 dri_version
, & dri_expected
,
731 ddx_version
, & ddx_expected
,
732 drm_version
, & drm_expected
) ) {
736 psp
= __driUtilCreateNewScreen(dpy
, scrn
, psc
, NULL
,
737 ddx_version
, dri_version
, drm_version
,
738 frame_buffer
, pSAREA
, fd
,
739 internal_api_version
, &ffbAPI
);
741 create_context_modes
= (PFNGLXCREATECONTEXTMODES
)
742 glXGetProcAddress( (const GLubyte
*) "__glXCreateContextModes" );
743 if ( create_context_modes
!= NULL
) {
744 *driver_modes
= ffbFillInModes( 32, 16, 0, GL_TRUE
);