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"
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"
62
#include "drirenderbuffer.h"
65
ffbInitDriver(__DRIscreenPrivate *sPriv)
67
ffbScreenPrivate *ffbScreen;
68
FFBDRIPtr gDRIPriv = (FFBDRIPtr) sPriv->pDevPriv;
71
if (getenv("LIBGL_FORCE_XSERVER"))
75
if (sPriv->devPrivSize != sizeof(FFBDRIRec)) {
76
fprintf(stderr,"\nERROR! sizeof(FFBDRIRec) does not match passed size from device driver\n");
80
/* Allocate the private area. */
81
ffbScreen = (ffbScreenPrivate *) MALLOC(sizeof(ffbScreenPrivate));
85
/* Map FBC registers. */
93
ffbScreen->regs = (ffb_fbcPtr) map;
95
/* Map ramdac registers. */
100
drmUnmap((drmAddress)ffbScreen->regs, gDRIPriv->sFbcRegs);
104
ffbScreen->dac = (ffb_dacPtr) map;
106
/* Map "Smart" framebuffer views. */
107
if (drmMap(sPriv->fd,
111
drmUnmap((drmAddress)ffbScreen->regs, gDRIPriv->sFbcRegs);
112
drmUnmap((drmAddress)ffbScreen->dac, gDRIPriv->sDacRegs);
116
ffbScreen->sfb8r = (volatile char *) map;
118
if (drmMap(sPriv->fd,
122
drmUnmap((drmAddress)ffbScreen->regs, gDRIPriv->sFbcRegs);
123
drmUnmap((drmAddress)ffbScreen->dac, gDRIPriv->sDacRegs);
124
drmUnmap((drmAddress)ffbScreen->sfb8r, gDRIPriv->sSfb8r);
128
ffbScreen->sfb32 = (volatile char *) map;
130
if (drmMap(sPriv->fd,
134
drmUnmap((drmAddress)ffbScreen->regs, gDRIPriv->sFbcRegs);
135
drmUnmap((drmAddress)ffbScreen->dac, gDRIPriv->sDacRegs);
136
drmUnmap((drmAddress)ffbScreen->sfb8r, gDRIPriv->sSfb8r);
137
drmUnmap((drmAddress)ffbScreen->sfb32, gDRIPriv->sSfb32);
141
ffbScreen->sfb64 = (volatile char *) map;
143
ffbScreen->fifo_cache = 0;
144
ffbScreen->rp_active = 0;
146
ffbScreen->sPriv = sPriv;
147
sPriv->private = (void *) ffbScreen;
150
ffbDDPointfuncInit();
157
ffbDestroyScreen(__DRIscreenPrivate *sPriv)
159
ffbScreenPrivate *ffbScreen = sPriv->private;
160
FFBDRIPtr gDRIPriv = (FFBDRIPtr) sPriv->pDevPriv;
162
drmUnmap((drmAddress)ffbScreen->regs, gDRIPriv->sFbcRegs);
163
drmUnmap((drmAddress)ffbScreen->dac, gDRIPriv->sDacRegs);
164
drmUnmap((drmAddress)ffbScreen->sfb8r, gDRIPriv->sSfb8r);
165
drmUnmap((drmAddress)ffbScreen->sfb32, gDRIPriv->sSfb32);
166
drmUnmap((drmAddress)ffbScreen->sfb64, gDRIPriv->sSfb64);
171
static const struct tnl_pipeline_stage *ffb_pipeline[] = {
172
&_tnl_vertex_transform_stage,
173
&_tnl_normal_transform_stage,
174
&_tnl_lighting_stage,
175
/* REMOVE: fog coord stage */
177
&_tnl_texture_transform_stage,
178
/* REMOVE: point attenuation stage */
183
/* Create and initialize the Mesa and driver specific context data */
185
ffbCreateContext(const __GLcontextModes *mesaVis,
186
__DRIcontextPrivate *driContextPriv,
187
void *sharedContextPrivate)
190
GLcontext *ctx, *shareCtx;
191
__DRIscreenPrivate *sPriv;
192
ffbScreenPrivate *ffbScreen;
194
struct dd_function_table functions;
196
/* Allocate ffb context */
197
fmesa = (ffbContextPtr) CALLOC(sizeof(ffbContextRec));
201
_mesa_init_driver_functions(&functions);
203
/* Allocate Mesa context */
204
if (sharedContextPrivate)
205
shareCtx = ((ffbContextPtr) sharedContextPrivate)->glCtx;
208
fmesa->glCtx = _mesa_create_context(mesaVis, shareCtx,
214
driContextPriv->driverPrivate = fmesa;
217
sPriv = driContextPriv->driScreenPriv;
218
ffbScreen = (ffbScreenPrivate *) sPriv->private;
221
fmesa->hHWContext = driContextPriv->hHWContext;
222
fmesa->driFd = sPriv->fd;
223
fmesa->driHwLock = &sPriv->pSAREA->lock;
225
fmesa->ffbScreen = ffbScreen;
226
fmesa->driScreen = sPriv;
227
fmesa->ffb_sarea = FFB_DRISHARE(sPriv->pSAREA);
229
/* Register and framebuffer hw pointers. */
230
fmesa->regs = ffbScreen->regs;
231
fmesa->sfb32 = ffbScreen->sfb32;
233
ffbDDInitContextHwState(ctx);
235
/* Default clear and depth colors. */
237
GLubyte r = (GLint) (ctx->Color.ClearColor[0] * 255.0F);
238
GLubyte g = (GLint) (ctx->Color.ClearColor[1] * 255.0F);
239
GLubyte b = (GLint) (ctx->Color.ClearColor[2] * 255.0F);
241
fmesa->clear_pixel = ((r << 0) |
245
fmesa->clear_depth = Z_FROM_MESA(ctx->Depth.Clear * 4294967295.0f);
246
fmesa->clear_stencil = ctx->Stencil.Clear & 0xf;
248
/* No wide points. */
249
ctx->Const.MinPointSize = 1.0;
250
ctx->Const.MinPointSizeAA = 1.0;
251
ctx->Const.MaxPointSize = 1.0;
252
ctx->Const.MaxPointSizeAA = 1.0;
254
/* Disable wide lines as we can't antialias them correctly in
257
ctx->Const.MinLineWidth = 1.0;
258
ctx->Const.MinLineWidthAA = 1.0;
259
ctx->Const.MaxLineWidth = 1.0;
260
ctx->Const.MaxLineWidthAA = 1.0;
261
ctx->Const.LineWidthGranularity = 1.0;
263
/* Instead of having GCC emit these constants a zillion times
264
* everywhere in the driver, put them here.
266
fmesa->ffb_2_30_fixed_scale = __FFB_2_30_FIXED_SCALE;
267
fmesa->ffb_one_over_2_30_fixed_scale = (1.0 / __FFB_2_30_FIXED_SCALE);
268
fmesa->ffb_16_16_fixed_scale = __FFB_16_16_FIXED_SCALE;
269
fmesa->ffb_one_over_16_16_fixed_scale = (1.0 / __FFB_16_16_FIXED_SCALE);
270
fmesa->ffb_ubyte_color_scale = 255.0f;
271
fmesa->ffb_zero = 0.0f;
273
fmesa->debugFallbacks = GL_FALSE;
274
debug = getenv("LIBGL_DEBUG");
275
if (debug && strstr(debug, "fallbacks"))
276
fmesa->debugFallbacks = GL_TRUE;
278
/* Initialize the software rasterizer and helper modules. */
279
_swrast_CreateContext( ctx );
280
_vbo_CreateContext( ctx );
281
_tnl_CreateContext( ctx );
282
_swsetup_CreateContext( ctx );
284
/* All of this need only be done once for a new context. */
285
/* XXX these should be moved right after the
286
* _mesa_init_driver_functions() call above.
288
ffbDDExtensionsInit(ctx);
289
ffbDDInitDriverFuncs(ctx);
290
ffbDDInitStateFuncs(ctx);
291
ffbDDInitRenderFuncs(ctx);
292
/*ffbDDInitTexFuncs(ctx); not needed */
293
ffbDDInitBitmapFuncs(ctx);
297
ffbInitTnlModule(ctx);
300
_tnl_destroy_pipeline(ctx);
301
_tnl_install_pipeline(ctx, ffb_pipeline);
307
ffbDestroyContext(__DRIcontextPrivate *driContextPriv)
309
ffbContextPtr fmesa = (ffbContextPtr) driContextPriv->driverPrivate;
312
ffbFreeVB(fmesa->glCtx);
314
_swsetup_DestroyContext( fmesa->glCtx );
315
_tnl_DestroyContext( fmesa->glCtx );
316
_vbo_DestroyContext( fmesa->glCtx );
317
_swrast_DestroyContext( fmesa->glCtx );
319
/* free the Mesa context */
320
fmesa->glCtx->DriverCtx = NULL;
321
_mesa_destroy_context(fmesa->glCtx);
327
/* Create and initialize the Mesa and driver specific pixmap buffer data */
329
ffbCreateBuffer(__DRIscreenPrivate *driScrnPriv,
330
__DRIdrawablePrivate *driDrawPriv,
331
const __GLcontextModes *mesaVis,
334
/* Mesa checks for pitch > 0, but ffb doesn't use pitches */
336
int bpp = 4; /* we've always got a 32bpp framebuffer */
337
int offset = 0; /* always at 0 for offset */
340
return GL_FALSE; /* not implemented */
342
GLboolean swStencil = (mesaVis->stencilBits > 0 &&
343
mesaVis->depthBits != 24);
344
struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
347
driRenderbuffer *frontRb
348
= driNewRenderbuffer(GL_RGBA, NULL, bpp, offset, bogusPitch,
350
ffbSetSpanFunctions(frontRb, mesaVis);
351
_mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base);
354
if (mesaVis->doubleBufferMode) {
355
driRenderbuffer *backRb
356
= driNewRenderbuffer(GL_RGBA, NULL, bpp, offset, bogusPitch,
358
ffbSetSpanFunctions(backRb, mesaVis);
359
_mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base);
362
if (mesaVis->depthBits == 16) {
363
driRenderbuffer *depthRb
364
= driNewRenderbuffer(GL_DEPTH_COMPONENT16, NULL, bpp, offset,
365
bogusPitch, driDrawPriv);
366
ffbSetDepthFunctions(depthRb, mesaVis);
367
_mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
370
if (mesaVis->stencilBits > 0 && !swStencil) {
371
driRenderbuffer *stencilRb
372
= driNewRenderbuffer(GL_STENCIL_INDEX8_EXT, NULL, bpp, offset,
373
bogusPitch, driDrawPriv);
374
ffbSetStencilFunctions(stencilRb, mesaVis);
375
_mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base);
378
_mesa_add_soft_renderbuffers(fb,
379
GL_FALSE, /* color */
380
GL_FALSE, /* depth */
382
mesaVis->accumRedBits > 0,
383
GL_FALSE, /* alpha */
385
driDrawPriv->driverPrivate = (void *) fb;
387
return (driDrawPriv->driverPrivate != NULL);
393
ffbDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
395
_mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
399
#define USE_FAST_SWAP
402
ffbSwapBuffers( __DRIdrawablePrivate *dPriv )
404
ffbContextPtr fmesa = (ffbContextPtr) dPriv->driContextPriv->driverPrivate;
405
unsigned int fbc, wid, wid_reg_val, dac_db_bit;
406
unsigned int shadow_dac_addr, active_dac_addr;
411
fmesa->glCtx->Visual.doubleBufferMode == 0)
414
/* Flush pending rendering commands */
415
_mesa_notifySwapBuffers(fmesa->glCtx);
418
dac = fmesa->ffbScreen->dac;
423
/* Swap the buffer we render into and read pixels from. */
424
fmesa->back_buffer ^= 1;
426
/* If we are writing into both buffers, don't mess with
429
if ((fbc & FFB_FBC_WB_AB) != FFB_FBC_WB_AB) {
430
if ((fbc & FFB_FBC_WB_A) != 0)
431
fbc = (fbc & ~FFB_FBC_WB_A) | FFB_FBC_WB_B;
433
fbc = (fbc & ~FFB_FBC_WB_B) | FFB_FBC_WB_A;
436
/* But either way, we must flip the read buffer setting. */
437
if ((fbc & FFB_FBC_RB_A) != 0)
438
fbc = (fbc & ~FFB_FBC_RB_A) | FFB_FBC_RB_B;
440
fbc = (fbc & ~FFB_FBC_RB_B) | FFB_FBC_RB_A;
442
LOCK_HARDWARE(fmesa);
444
if (fmesa->fbc != fbc) {
446
ffb->fbc = fmesa->fbc = fbc;
447
fmesa->ffbScreen->rp_active = 1;
450
/* And swap the buffer displayed in the WID. */
451
if (fmesa->ffb_sarea->flags & FFB_DRI_PAC1) {
452
shadow_dac_addr = FFBDAC_PAC1_SPWLUT(wid);
453
active_dac_addr = FFBDAC_PAC1_APWLUT(wid);
454
dac_db_bit = FFBDAC_PAC1_WLUT_DB;
456
shadow_dac_addr = FFBDAC_PAC2_SPWLUT(wid);
457
active_dac_addr = FFBDAC_PAC2_APWLUT(wid);
458
dac_db_bit = FFBDAC_PAC2_WLUT_DB;
463
wid_reg_val = DACCFG_READ(dac, active_dac_addr);
464
if (fmesa->back_buffer == 0)
465
wid_reg_val |= dac_db_bit;
467
wid_reg_val &= ~dac_db_bit;
469
DACCFG_WRITE(dac, active_dac_addr, wid_reg_val);
471
DACCFG_WRITE(dac, shadow_dac_addr, wid_reg_val);
473
/* Schedule the window transfer. */
474
DACCFG_WRITE(dac, FFBDAC_CFG_WTCTRL,
475
(FFBDAC_CFG_WTCTRL_TCMD | FFBDAC_CFG_WTCTRL_TE));
480
unsigned int wtctrl = DACCFG_READ(dac, FFBDAC_CFG_WTCTRL);
482
if ((wtctrl & FFBDAC_CFG_WTCTRL_DS) == 0)
488
UNLOCK_HARDWARE(fmesa);
491
static void ffb_init_wid(ffbContextPtr fmesa, unsigned int wid)
493
ffb_dacPtr dac = fmesa->ffbScreen->dac;
494
unsigned int wid_reg_val, dac_db_bit, active_dac_addr;
495
unsigned int shadow_dac_addr;
497
if (fmesa->ffb_sarea->flags & FFB_DRI_PAC1) {
498
shadow_dac_addr = FFBDAC_PAC1_SPWLUT(wid);
499
active_dac_addr = FFBDAC_PAC1_APWLUT(wid);
500
dac_db_bit = FFBDAC_PAC1_WLUT_DB;
502
shadow_dac_addr = FFBDAC_PAC2_SPWLUT(wid);
503
active_dac_addr = FFBDAC_PAC2_APWLUT(wid);
504
dac_db_bit = FFBDAC_PAC2_WLUT_DB;
507
wid_reg_val = DACCFG_READ(dac, active_dac_addr);
508
wid_reg_val &= ~dac_db_bit;
510
DACCFG_WRITE(dac, active_dac_addr, wid_reg_val);
512
DACCFG_WRITE(dac, shadow_dac_addr, wid_reg_val);
514
/* Schedule the window transfer. */
515
DACCFG_WRITE(dac, FFBDAC_CFG_WTCTRL,
516
(FFBDAC_CFG_WTCTRL_TCMD | FFBDAC_CFG_WTCTRL_TE));
521
unsigned int wtctrl = DACCFG_READ(dac, FFBDAC_CFG_WTCTRL);
523
if ((wtctrl & FFBDAC_CFG_WTCTRL_DS) == 0)
530
/* Force the context `c' to be the current context and associate with it
533
ffbMakeCurrent(__DRIcontextPrivate *driContextPriv,
534
__DRIdrawablePrivate *driDrawPriv,
535
__DRIdrawablePrivate *driReadPriv)
537
if (driContextPriv) {
538
ffbContextPtr fmesa = (ffbContextPtr) driContextPriv->driverPrivate;
541
fmesa->driDrawable = driDrawPriv;
543
_mesa_make_current(fmesa->glCtx,
544
(GLframebuffer *) driDrawPriv->driverPrivate,
545
(GLframebuffer *) driReadPriv->driverPrivate);
548
if (fmesa->wid == ~0) {
550
if (getenv("LIBGL_SOFTWARE_RENDERING"))
551
FALLBACK( fmesa->glCtx, FFB_BADATTR_SWONLY, GL_TRUE );
554
LOCK_HARDWARE(fmesa);
556
fmesa->wid = fmesa->ffb_sarea->wid_table[driDrawPriv->index];
557
ffb_init_wid(fmesa, fmesa->wid);
560
fmesa->state_dirty |= FFB_STATE_ALL;
561
fmesa->state_fifo_ents = fmesa->state_all_fifo_ents;
562
ffbSyncHardware(fmesa);
563
UNLOCK_HARDWARE(fmesa);
566
/* Also, at the first switch to a new context,
567
* we need to clear all the hw buffers.
569
ffbDDClear(fmesa->glCtx,
570
(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT |
571
BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL));
574
_mesa_make_current(NULL, NULL, NULL);
580
/* Force the context `c' to be unbound from its buffer */
582
ffbUnbindContext(__DRIcontextPrivate *driContextPriv)
587
void ffbXMesaUpdateState(ffbContextPtr fmesa)
589
__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
590
__DRIscreenPrivate *sPriv = fmesa->driScreen;
591
int stamp = dPriv->lastStamp;
593
DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
595
if (dPriv->lastStamp != stamp) {
596
GLcontext *ctx = fmesa->glCtx;
598
ffbCalcViewport(ctx);
599
driUpdateFramebufferSize(ctx, dPriv);
600
if (ctx->Polygon.StippleFlag) {
601
ffbXformAreaPattern(fmesa,
602
(const GLubyte *)ctx->PolygonStipple);
607
static const struct __DriverAPIRec ffbAPI = {
608
.InitDriver = ffbInitDriver,
609
.DestroyScreen = ffbDestroyScreen,
610
.CreateContext = ffbCreateContext,
611
.DestroyContext = ffbDestroyContext,
612
.CreateBuffer = ffbCreateBuffer,
613
.DestroyBuffer = ffbDestroyBuffer,
614
.SwapBuffers = ffbSwapBuffers,
615
.MakeCurrent = ffbMakeCurrent,
616
.UnbindContext = ffbUnbindContext,
621
.SwapBuffersMSC = NULL
625
static __GLcontextModes *
626
ffbFillInModes( unsigned pixel_bits, unsigned depth_bits,
627
unsigned stencil_bits, GLboolean have_back_buffer )
629
__GLcontextModes * modes;
630
__GLcontextModes * m;
632
unsigned depth_buffer_factor;
633
unsigned back_buffer_factor;
637
/* GLX_SWAP_COPY_OML is only supported because the FFB driver doesn't
638
* support pageflipping at all.
640
static const GLenum back_buffer_modes[] = {
641
GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
644
u_int8_t depth_bits_array[3];
645
u_int8_t stencil_bits_array[3];
648
depth_bits_array[0] = 0;
649
depth_bits_array[1] = depth_bits;
650
depth_bits_array[2] = depth_bits;
652
/* Just like with the accumulation buffer, always provide some modes
653
* with a stencil buffer. It will be a sw fallback, but some apps won't
656
stencil_bits_array[0] = 0;
657
stencil_bits_array[1] = 0;
658
stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits;
660
depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1;
661
back_buffer_factor = (have_back_buffer) ? 3 : 1;
663
num_modes = depth_buffer_factor * back_buffer_factor * 4;
665
if ( pixel_bits == 16 ) {
667
fb_type = GL_UNSIGNED_SHORT_5_6_5;
671
fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
674
modes = (*dri_interface->createContextModes)( num_modes, sizeof( __GLcontextModes ) );
676
if ( ! driFillInModes( & m, fb_format, fb_type,
677
depth_bits_array, stencil_bits_array, depth_buffer_factor,
678
back_buffer_modes, back_buffer_factor,
680
fprintf( stderr, "[%s:%u] Error creating FBConfig!\n",
681
__func__, __LINE__ );
684
if ( ! driFillInModes( & m, fb_format, fb_type,
685
depth_bits_array, stencil_bits_array, depth_buffer_factor,
686
back_buffer_modes, back_buffer_factor,
687
GLX_DIRECT_COLOR ) ) {
688
fprintf( stderr, "[%s:%u] Error creating FBConfig!\n",
689
__func__, __LINE__ );
694
/* Mark the visual as slow if there are "fake" stencil bits.
696
for ( m = modes ; m != NULL ; m = m->next ) {
697
if ( (m->stencilBits != 0) && (m->stencilBits != stencil_bits) ) {
698
m->visualRating = GLX_SLOW_CONFIG;
707
* This is the bootstrap function for the driver. libGL supplies all of the
708
* requisite information about the system, and the driver initializes itself.
709
* This routine also fills in the linked list pointed to by \c driver_modes
710
* with the \c __GLcontextModes that the driver can support for windows or
713
* \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
717
void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
718
const __GLcontextModes * modes,
719
const __DRIversion * ddx_version,
720
const __DRIversion * dri_version,
721
const __DRIversion * drm_version,
722
const __DRIframebuffer * frame_buffer,
723
drmAddress pSAREA, int fd,
724
int internal_api_version,
725
const __DRIinterfaceMethods * interface,
726
__GLcontextModes ** driver_modes )
729
__DRIscreenPrivate *psp;
730
static const __DRIversion ddx_expected = { 0, 1, 1 };
731
static const __DRIversion dri_expected = { 4, 0, 0 };
732
static const __DRIversion drm_expected = { 0, 0, 1 };
734
dri_interface = interface;
736
if ( ! driCheckDriDdxDrmVersions2( "ffb",
737
dri_version, & dri_expected,
738
ddx_version, & ddx_expected,
739
drm_version, & drm_expected ) ) {
743
psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
744
ddx_version, dri_version, drm_version,
745
frame_buffer, pSAREA, fd,
746
internal_api_version, &ffbAPI);
748
*driver_modes = ffbFillInModes( 32, 16, 0, GL_TRUE );