Site hosted by Angelfire.com: Build your free website today!

Hands-on Projects for the Linux Graphics Subsystem

New book from Christos Karayiannis

Available in Amazon Kindle format at:

amazon.com   amazon.co.uk   amazon.de   amazon.es   amazon.fr   amazon.it

fbScreenInit()

We read from the Distributed Multihead X design:

{mi,*fb}ScreenInit()

The DDX layer's ScreenInit() function usually calls another layer's ScreenInit() function (e.g., miScreenInit() or fbScreenInit()) to initialize the fallbacks that the DDX driver does not specifically handle.

After calling another layer's ScreenInit() function, any screen-specific functions either wrap or replace the other layer's function pointers. If a function is to be wrapped, each of the old function pointers from the other layer are stored in a screen private area. Common functions to wrap are CloseScreen() and SaveScreen().

fbScreenInit() is used to tell the fb layer where the video card framebuffer is.

It is called from MGAScreenInit() as:

	ret = fbScreenInit(pScreen, FBStart, width, height,
			   pScrn->xDpi, pScrn->yDpi,
			   displayWidth, pScrn->bitsPerPixel);

For a description of the fbScreenInit() arguments see section 3.2.2.11.

fbScreenInit() is implemented as:

Bool
fbScreenInit(ScreenPtr	pScreen,
	     pointer	pbits,
	     int	xsize,
	     int	ysize,
	     int	dpix,
	     int	dpiy,
	     int	width,
	     int	bpp)
{
    if (!fbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp))
	return FALSE;
    if (!fbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, 
			    width, bpp))
	return FALSE;
    return TRUE;
}

Notice that fbScreenInit calls 'width' the seventh of its formal arguments, which was substituted by the actual argument 'displayWidth'. At the same time there is a third actual argument also called 'width' (see this Wiki). This might cause some misunderstanding. Anyway as width the displayWidth will be used next. This is the stride as we saw in section 3.2.2.11.

fbSetupScreen() is implemented as:

Bool
fbSetupScreen(ScreenPtr	pScreen, 
	      pointer	pbits,		/* pointer to screen bitmap */
	      int	xsize, 		/* in pixels */
	      int	ysize,
	      int	dpix,		/* dots per inch */
	      int	dpiy,
	      int	width,		/* pixel width of frame buffer */
	      int	bpp)		/* bits per pixel for screen */
{
    if (!fbAllocatePrivates(pScreen, (int *) 0))
	return FALSE;
    pScreen->defColormap = FakeClientID(0);
    /* let CreateDefColormap do whatever it wants for pixels */ 
    pScreen->blackPixel = pScreen->whitePixel = (Pixel) 0;
    pScreen->QueryBestSize = fbQueryBestSize;
    /* SaveScreen */
    pScreen->GetImage = fbGetImage;
    pScreen->GetSpans = fbGetSpans;
    pScreen->CreateWindow = fbCreateWindow;
    pScreen->DestroyWindow = fbDestroyWindow;
    pScreen->PositionWindow = fbPositionWindow;
    pScreen->ChangeWindowAttributes = fbChangeWindowAttributes;
    pScreen->RealizeWindow = fbMapWindow;
    pScreen->UnrealizeWindow = fbUnmapWindow;
    pScreen->PaintWindowBackground = fbPaintWindow;
    pScreen->PaintWindowBorder = fbPaintWindow;
    pScreen->CopyWindow = fbCopyWindow;
    pScreen->CreatePixmap = fbCreatePixmap;
    pScreen->DestroyPixmap = fbDestroyPixmap;
    pScreen->RealizeFont = fbRealizeFont;
    pScreen->UnrealizeFont = fbUnrealizeFont;
    pScreen->CreateGC = fbCreateGC;
    pScreen->CreateColormap = fbInitializeColormap;
    pScreen->DestroyColormap = (void (*)(ColormapPtr))NoopDDA;
    pScreen->InstallColormap = fbInstallColormap;
    pScreen->UninstallColormap = fbUninstallColormap;
    pScreen->ListInstalledColormaps = fbListInstalledColormaps;
    pScreen->StoreColors = (void (*)(ColormapPtr, int, xColorItem *))NoopDDA;
    pScreen->ResolveColor = fbResolveColor;
    pScreen->BitmapToRegion = fbPixmapToRegion;
    
#ifndef FB_OLD_SCREEN
    pScreen->GetWindowPixmap = _fbGetWindowPixmap;
    pScreen->SetWindowPixmap = _fbSetWindowPixmap;

    pScreen->BackingStoreFuncs.SaveAreas = fbSaveAreas;
    pScreen->BackingStoreFuncs.RestoreAreas = fbRestoreAreas;
    pScreen->BackingStoreFuncs.SetClipmaskRgn = 0;
    pScreen->BackingStoreFuncs.GetImagePixmap = 0;
    pScreen->BackingStoreFuncs.GetSpansPixmap = 0;
#endif
    
    return TRUE;
}

The pScreen pointer to the current ScreenRec, which is passed as the first argument to fbScreenInit() fills many of the of its pointer to functions fields. The process of filling the current ScreenRec started at section 3.2.2.10 with AddScreen().

fbFinishScreenInit() is implemented as:

Bool
fbFinishScreenInit(ScreenPtr	pScreen,
		   pointer	pbits,
		   int		xsize,
		   int		ysize,
		   int		dpix,
		   int		dpiy,
		   int		width,
		   int		bpp)
{
    VisualPtr	visuals;
    DepthPtr	depths;
    int		nvisuals;
    int		ndepths;
    int		rootdepth;
    VisualID	defaultVisual;
    int		imagebpp = bpp;

#ifdef FB_DEBUG
    int	stride;
    
    ysize -= 2;
    stride = (width * bpp) / 8;
    fbSetBits ((FbStip *) pbits, 
	       stride / sizeof (FbStip), FB_HEAD_BITS);
    pbits = (void *) ((char *) pbits + stride);
    fbSetBits ((FbStip *) ((char *) pbits + stride * ysize),
			   stride / sizeof (FbStip), FB_TAIL_BITS);
#endif
    /*
     * By default, a 24bpp screen will use 32bpp images, this avoids
     * problems with many applications which just can't handle packed
     * pixels.  If you want real 24bit images, include a 24bpp
     * format in the pixmap formats
     */
#ifdef FB_24_32BIT
    if (bpp == 24)
    {
	int	f;
	
	imagebpp = 32;
	/*
	 * Check to see if we're advertising a 24bpp image format,
	 * in which case windows will use it in preference to a 32 bit
	 * format.
	 */
	for (f = 0; f < screenInfo.numPixmapFormats; f++)
	{
	    if (screenInfo.formats[f].bitsPerPixel == 24)
	    {
		imagebpp = 24;
		break;
	    }
	}	    
    }
#endif
#ifdef FB_SCREEN_PRIVATE
    if (imagebpp == 32)
    {
	fbGetScreenPrivate(pScreen)->win32bpp = bpp;
	fbGetScreenPrivate(pScreen)->pix32bpp = bpp;
    }
    else
    {
	fbGetScreenPrivate(pScreen)->win32bpp = 32;
	fbGetScreenPrivate(pScreen)->pix32bpp = 32;
    }
#endif
    rootdepth = 0;
    if (!fbInitVisuals (&visuals, &depths, &nvisuals, &ndepths, &rootdepth,
			&defaultVisual,((unsigned long)1<<(imagebpp-1)), 8))
	return FALSE;
    if (! miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
			rootdepth, ndepths, depths,
			defaultVisual, nvisuals, visuals
#ifdef FB_OLD_MISCREENINIT
		       , (miBSFuncPtr) 0
#endif
		       ))
	return FALSE;
    /* overwrite miCloseScreen with our own */
    pScreen->CloseScreen = fbCloseScreen;
#ifdef FB_24_32BIT
    if (bpp == 24 && imagebpp == 32)
    {
	pScreen->ModifyPixmapHeader = fb24_32ModifyPixmapHeader;
	pScreen->CreateScreenResources = fb24_32CreateScreenResources;
    }
#endif
#if 0
    /* leave backing store initialization to the enclosing code so
     * it can choose the correct order of wrappers
     */
    /* init backing store here so we can overwrite CloseScreen without stepping
     * on the backing store wrapped version */
    fbInitializeBackingStore (pScreen);
#endif
    return TRUE;
}

From this wiki we read about stride:

Buffers in video ram generally have a stride (also called pitch) associated with them. The stride is the width of the buffer in bytes. For example, if you have a 1024x768 pixel buffer at 16 bits/pixel (2 bytes/pixel), your stride would be:

1024 pixels * 2 bytes/pixel = 2048 bytesAt 32 bits/pixel (4 bytes/pixel), your stride would be:

1024 pixels * 4 bytes/pixel = 4096 bytes

Stride is important as it delineates where each line of the buffer starts and ends. With a linear buffer format, each line of the buffer follows the previous linearly in video ram:

framebuffer address
0              2048            4096
|---------------|---------------|---------------| ... |---------------|

The fbSetBits() usage is only for debugging purposes (#ifdef FB_DEBUG). It is implemented as:

void
fbSetBits (FbStip *bits, int stride, FbStip data)
{
    while (stride--)
	*bits++ = data;
}

Also macros FB_HEAD_BITS and FB_TAIL_BITS are defined in fd.h as:

 
#define FB_HEAD_BITS   (FbStip) (0xbaadf00d)
#define FB_TAIL_BITS   (FbStip) (0xbaddf0ad)

fbInitVisuals() handles 'visuals'.

For some texts on visuals see the following links:
Basic X Concepts
Visual Types

fbInitVisuals() is implemented as:

/*
 * Given a list of formats for a screen, create a list
 * of visuals and depths for the screen which correspond to
 * the set which can be used with this version of fb.
 */

Bool
fbInitVisuals (VisualPtr    *visualp, 
	       DepthPtr	    *depthp,
	       int	    *nvisualp,
	       int	    *ndepthp,
	       int	    *rootDepthp,
	       VisualID	    *defaultVisp,
	       unsigned long	sizes,
	       int	    bitsPerRGB)
{
    int		i, j = 0, k;
    VisualPtr	visual;
    DepthPtr	depth;
    VisualID	*vid;
    int		d, b;
    int		f;
    int		ndepth, nvisual;
    int		nvtype;
    int		vtype;
    fbVisualsPtr   visuals, nextVisuals;

    /* none specified, we'll guess from pixmap formats */
    if (!fbVisuals) 
    {
    	for (f = 0; f < screenInfo.numPixmapFormats; f++) 
    	{
	    d = screenInfo.formats[f].depth;
	    b = screenInfo.formats[f].bitsPerPixel;
	    if (sizes & (1 << (b - 1)))
	    {
	    	if (d > MAX_PSEUDO_DEPTH)
		    vtype = LARGE_VISUALS;
	    	else if (d == 1)
		    vtype = StaticGrayMask;
		else
		    vtype = ALL_VISUALS;
	    }
	    else
		vtype = 0;
	    if (!fbSetVisualTypes (d, vtype, bitsPerRGB))
		return FALSE;
    	}
    }
    nvisual = 0;
    ndepth = 0;
    for (visuals = fbVisuals; visuals; visuals = nextVisuals) 
    {
	nextVisuals = visuals->next;
	ndepth++;
	nvisual += visuals->count;
    }
    depth = (DepthPtr) xalloc (ndepth * sizeof (DepthRec));
    visual = (VisualPtr) xalloc (nvisual * sizeof (VisualRec));
    if (!depth || !visual)
    {
	xfree (depth);
	xfree (visual);
	return FALSE;
    }
    *depthp = depth;
    *visualp = visual;
    *ndepthp = ndepth;
    *nvisualp = nvisual;
    for (visuals = fbVisuals; visuals; visuals = nextVisuals) 
    {
	nextVisuals = visuals->next;
	d = visuals->depth;
	vtype = visuals->visuals;
	nvtype = visuals->count;
	vid = NULL;
	if (nvtype)
	{
	    vid = (VisualID *) xalloc (nvtype * sizeof (VisualID));
	    if (!vid)
		return FALSE;
	}
	depth->depth = d;
	depth->numVids = nvtype;
	depth->vids = vid;
	depth++;
	for (i = 0; i < NUM_PRIORITY; i++) {
	    if (! (vtype & (1 << fbVisualPriority[i])))
		continue;
	    visual->class = fbVisualPriority[i];
	    visual->bitsPerRGBValue = visuals->bitsPerRGB;
	    visual->ColormapEntries = 1 << d;
	    visual->nplanes = d;
	    visual->vid = *vid = FakeClientID (0);
	    switch (visual->class) {
	    case PseudoColor:
	    case GrayScale:
	    case StaticGray:
	    case StaticColor:
		visual->redMask = 0;
		visual->greenMask =  0;
		visual->blueMask =  0;
		visual->offsetRed  =  0;
		visual->offsetGreen = 0;
		visual->offsetBlue =  0;
		break;
	    case DirectColor:
	    case TrueColor:
		visual->ColormapEntries = _CE(d);
		visual->redMask =  visuals->redMask;
		visual->greenMask =  visuals->greenMask;
		visual->blueMask =  visuals->blueMask;
		visual->offsetRed  =  maskShift (visuals->redMask);
		visual->offsetGreen = maskShift (visuals->greenMask);
		visual->offsetBlue =  maskShift (visuals->blueMask);
	    }
	    vid++;
	    visual++;
	}
	xfree (visuals);
    }
    fbVisuals = NULL;
    visual = *visualp;
    depth = *depthp;
    for (i = 0; i < ndepth; i++)
    {
	if (*rootDepthp && *rootDepthp != depth[i].depth)
	    continue;
	for (j = 0; j < depth[i].numVids; j++)
	{
	    for (k = 0; k < nvisual; k++)
		if (visual[k].vid == depth[i].vids[j])
		    break;
	    if (k == nvisual)
		continue;
	    if (defaultColorVisualClass < 0 ||
		visual[k].class == defaultColorVisualClass)
		break;
	}
	if (j != depth[i].numVids)
	    break;
    }
    if (i == ndepth) {
	for (i = 0; i < ndepth; i++)
	{
	    if (depth[i].numVids)
		break;
	}
	if (i == ndepth)
	    return FALSE;
	j = 0;
    }
    *rootDepthp = depth[i].depth;
    *defaultVisp = depth[i].vids[j];
    return TRUE;
}

miScreenInit() is implemented as:

Bool
miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
	     rootDepth, numDepths, depths, rootVisual, numVisuals, visuals)
    register ScreenPtr pScreen;
    pointer pbits;		/* pointer to screen bits */
    int xsize, ysize;		/* in pixels */
    int dpix, dpiy;		/* dots per inch */
    int width;			/* pixel width of frame buffer */
    int rootDepth;		/* depth of root window */
    int numDepths;		/* number of depths supported */
    DepthRec *depths;		/* supported depths */
    VisualID rootVisual;	/* root visual */
    int numVisuals;		/* number of visuals supported */
    VisualRec *visuals;		/* supported visuals */
{
    pScreen->width = xsize;
    pScreen->height = ysize;
    pScreen->mmWidth = (xsize * 254 + dpix * 5) / (dpix * 10);
    pScreen->mmHeight = (ysize * 254 + dpiy * 5) / (dpiy * 10);
    pScreen->numDepths = numDepths;
    pScreen->rootDepth = rootDepth;
    pScreen->allowedDepths = depths;
    pScreen->rootVisual = rootVisual;
    /* defColormap */
    pScreen->minInstalledCmaps = 1;
    pScreen->maxInstalledCmaps = 1;
    pScreen->backingStoreSupport = NotUseful;
    pScreen->saveUnderSupport = NotUseful;
    /* whitePixel, blackPixel */
    pScreen->ModifyPixmapHeader = miModifyPixmapHeader;
    pScreen->CreateScreenResources = miCreateScreenResources;
    pScreen->GetScreenPixmap = miGetScreenPixmap;
    pScreen->SetScreenPixmap = miSetScreenPixmap;
    pScreen->numVisuals = numVisuals;
    pScreen->visuals = visuals;
    if (width)
    {
#ifdef MITSHM
	ShmRegisterFbFuncs(pScreen);
#endif
	pScreen->CloseScreen = miCloseScreen;
    }
    /* else CloseScreen */
    /* QueryBestSize, SaveScreen, GetImage, GetSpans */
    pScreen->PointerNonInterestBox = (PointerNonInterestBoxProcPtr) 0;
    pScreen->SourceValidate = (SourceValidateProcPtr) 0;
    /* CreateWindow, DestroyWindow, PositionWindow, ChangeWindowAttributes */
    /* RealizeWindow, UnrealizeWindow */
    pScreen->ValidateTree = miValidateTree;
    pScreen->PostValidateTree = (PostValidateTreeProcPtr) 0;
    pScreen->WindowExposures = miWindowExposures;
    /* PaintWindowBackground, PaintWindowBorder, CopyWindow */
    pScreen->ClearToBackground = miClearToBackground;
    pScreen->ClipNotify = (ClipNotifyProcPtr) 0;
    pScreen->RestackWindow = (RestackWindowProcPtr) 0;
    /* CreatePixmap, DestroyPixmap */
    /* RealizeFont, UnrealizeFont */
    /* CreateGC */
    /* CreateColormap, DestroyColormap, InstallColormap, UninstallColormap */
    /* ListInstalledColormaps, StoreColors, ResolveColor */
#ifdef NEED_SCREEN_REGIONS
    pScreen->RegionCreate = miRegionCreate;
    pScreen->RegionInit = miRegionInit;
    pScreen->RegionCopy = miRegionCopy;
    pScreen->RegionDestroy = miRegionDestroy;
    pScreen->RegionUninit = miRegionUninit;
    pScreen->Intersect = miIntersect;
    pScreen->Union = miUnion;
    pScreen->Subtract = miSubtract;
    pScreen->Inverse = miInverse;
    pScreen->RegionReset = miRegionReset;
    pScreen->TranslateRegion = miTranslateRegion;
    pScreen->RectIn = miRectIn;
    pScreen->PointInRegion = miPointInRegion;
    pScreen->RegionNotEmpty = miRegionNotEmpty;
    pScreen->RegionEqual = miRegionEqual;
    pScreen->RegionBroken = miRegionBroken;
    pScreen->RegionBreak = miRegionBreak;
    pScreen->RegionEmpty = miRegionEmpty;
    pScreen->RegionExtents = miRegionExtents;
    pScreen->RegionAppend = miRegionAppend;
    pScreen->RegionValidate = miRegionValidate;
#endif /* NEED_SCREEN_REGIONS */
    /* BitmapToRegion */
#ifdef NEED_SCREEN_REGIONS
    pScreen->RectsToRegion = miRectsToRegion;
#endif /* NEED_SCREEN_REGIONS */
    pScreen->SendGraphicsExpose = miSendGraphicsExpose;
    pScreen->BlockHandler = (ScreenBlockHandlerProcPtr)NoopDDA;
    pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr)NoopDDA;
    pScreen->blockData = (pointer)0;
    pScreen->wakeupData = (pointer)0;
    pScreen->MarkWindow = miMarkWindow;
    pScreen->MarkOverlappedWindows = miMarkOverlappedWindows;
    pScreen->ChangeSaveUnder = miChangeSaveUnder;
    pScreen->PostChangeSaveUnder = miPostChangeSaveUnder;
    pScreen->MoveWindow = miMoveWindow;
    pScreen->ResizeWindow = miSlideAndSizeWindow;
    pScreen->GetLayerWindow = miGetLayerWindow;
    pScreen->HandleExposures = miHandleValidateExposures;
    pScreen->ReparentWindow = (ReparentWindowProcPtr) 0;
    pScreen->ChangeBorderWidth = miChangeBorderWidth;
#ifdef SHAPE
    pScreen->SetShape = miSetShape;
#endif
    pScreen->MarkUnrealizedWindow = miMarkUnrealizedWindow;

    pScreen->SaveDoomedAreas = 0;
    pScreen->RestoreAreas = 0;
    pScreen->ExposeCopy = 0;
    pScreen->TranslateBackingStore = 0;
    pScreen->ClearBackingStore = 0;
    pScreen->DrawGuarantee = 0;

    miSetZeroLineBias(pScreen, DEFAULTZEROLINEBIAS);

    return miScreenDevPrivateInit(pScreen, width, pbits);
}

miScreenDevPrivateInit() is implemented as:

Bool
miScreenDevPrivateInit(pScreen, width, pbits)
    register ScreenPtr pScreen;
    int width;
    pointer pbits;
{
    miScreenInitParmsPtr pScrInitParms;

    /* Stash pbits and width in a short-lived miScreenInitParmsRec attached
     * to the screen, until CreateScreenResources can put them in the
     * screen pixmap.
     */
    pScrInitParms = (miScreenInitParmsPtr)xalloc(sizeof(miScreenInitParmsRec));
    if (!pScrInitParms)
	return FALSE;
    pScrInitParms->pbits = pbits;
    pScrInitParms->width = width;
    pScreen->devPrivate = (pointer)pScrInitParms;
    return TRUE;
}

The framebuffer address (FBStart), which was named pbits in the functions called by fbScreenInit() is finally used here as a field of the struct that devPrivate points. Pointer devPrivate is a field of ScreenRec.

Note also the following comment at the definition of miScreenInitParmsRec:

/* We use this structure to propogate some information from miScreenInit to
 * miCreateScreenResources.  miScreenInit allocates the structure, fills it
 * in, and puts it into pScreen->devPrivate.  miCreateScreenResources 
 * extracts the info and frees the structure.  We could've accomplished the
 * same thing by adding fields to the screen structure, but they would have
 * ended up being redundant, and would have exposed this mi implementation
 * detail to the whole server.
 */

typedef struct
{
    pointer pbits; /* pointer to framebuffer */
    int width;    /* delta to add to a framebuffer addr to move one row down */
} miScreenInitParmsRec, *miScreenInitParmsPtr;

As the comment in the source notes 'pbits' and 'width' will be used next by CreateScreenResources(), which was called in main() after the InitOutput() as:

	for (i = 0; i < screenInfo.numScreens; i++)
	{
	    ScreenPtr pScreen = screenInfo.screens[i];
	    if (!CreateScratchPixmapsForScreen(i))
		FatalError("failed to create scratch pixmaps");
	    if (pScreen->CreateScreenResources &&
		!(*pScreen->CreateScreenResources)(pScreen))
		FatalError("failed to create screen resources");

Previously as CreateScreenResources() was set miCreateScreenResources() by miScreenInit().

miCreateScreenResources() is implemented as:

/* With the introduction of pixmap privates, the "screen pixmap" can no
 * longer be created in miScreenInit, since all the modules that could
 * possibly ask for pixmap private space have not been initialized at
 * that time.  pScreen->CreateScreenResources is called after all
 * possible private-requesting modules have been inited; we create the
 * screen pixmap here.
 */
Bool
miCreateScreenResources(pScreen)
    ScreenPtr pScreen;
{
    miScreenInitParmsPtr pScrInitParms;
    pointer value;

    pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate;

    /* if width is non-zero, pScreen->devPrivate will be a pixmap
     * else it will just take the value pbits
     */
    if (pScrInitParms->width)
    {
	PixmapPtr pPixmap;

	/* create a pixmap with no data, then redirect it to point to
	 * the screen
	 */
	pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth);
	if (!pPixmap)
	    return FALSE;

	if (!(*pScreen->ModifyPixmapHeader)(pPixmap, pScreen->width,
		    pScreen->height, pScreen->rootDepth,
		    BitsPerPixel(pScreen->rootDepth),
		    PixmapBytePad(pScrInitParms->width, pScreen->rootDepth),
		    pScrInitParms->pbits))
	    return FALSE;
	value = (pointer)pPixmap;
    }
    else
    {
	value = pScrInitParms->pbits;
    }
    xfree(pScreen->devPrivate); /* freeing miScreenInitParmsRec */
    pScreen->devPrivate = value; /* pPixmap or pbits */
    return TRUE;
}

At this point pScreen->devPrivate takes the value of either pbits (the pointer to the screen memory) or pPixmap (again the pointer to the screen memory, this time however there is a displayWidth a.k.a. 'stride').

The choice is made according to the value of pScrInitParms->width, which is the displayWidth. A value was assigned to displayWidth at MGAPreInit() when xf86ValidateModes() was called. As we read from its comment:

 * The function fills in the following ScrnInfoRec fields:
 *    modePool     A subset of the modes available to the monitor which
 *		   are compatible with the driver.
 *    modes        one mode entry for each of the requested modes, with the
 *                 status field filled in to indicate if the mode has been
 *                 accepted or not.
 *    virtualX     the resulting virtual width
 *    virtualY     the resulting virtual height
 *    displayWidth the resulting line pitch

The comment in the beginning of miCreateScreenResources() explains that this function should be called after "all possible private-requesting modules have been inited", which implies that the following instruction should be called:

InitExtensions(argc, argv);
This is called from main() just after InitOutput().

fbCreatePixmap() is imlpemented as:

PixmapPtr
fbCreatePixmap (ScreenPtr pScreen, int width, int height, int depth)
{
    int	bpp;
    bpp = BitsPerPixel (depth);
#ifdef FB_SCREEN_PRIVATE
    if (bpp == 32 && depth <= 24)
	bpp = fbGetScreenPrivate(pScreen)->pix32bpp;
#endif
    return fbCreatePixmapBpp (pScreen, width, height, depth, bpp);
}

where fbCreatePixmapBpp() is implemented in the same file as:

PixmapPtr
fbCreatePixmapBpp (ScreenPtr pScreen, int width, int height, int depth, int bpp)
{
    PixmapPtr	pPixmap;
    size_t	datasize;
    size_t	paddedWidth;
    int		adjust;
    int		base;

    paddedWidth = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (FbBits);
    if (paddedWidth / 4 > 32767 || height > 32767)
	return NullPixmap;
    datasize = height * paddedWidth;
#ifdef PIXPRIV
    base = pScreen->totalPixmapSize;
#else
    base = sizeof (PixmapRec);
#endif
    adjust = 0;
    if (base & 7)
	adjust = 8 - (base & 7);
    datasize += adjust;
#ifdef FB_DEBUG
    datasize += 2 * paddedWidth;
#endif
    pPixmap = AllocatePixmap(pScreen, datasize);
    if (!pPixmap)
	return NullPixmap;
    pPixmap->drawable.type = DRAWABLE_PIXMAP;
    pPixmap->drawable.class = 0;
    pPixmap->drawable.pScreen = pScreen;
    pPixmap->drawable.depth = depth;
    pPixmap->drawable.bitsPerPixel = bpp;
    pPixmap->drawable.id = 0;
    pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
    pPixmap->drawable.x = 0;
    pPixmap->drawable.y = 0;
    pPixmap->drawable.width = width;
    pPixmap->drawable.height = height;
    pPixmap->devKind = paddedWidth;
    pPixmap->refcnt = 1;
    pPixmap->devPrivate.ptr = (pointer) ((char *)pPixmap + base + adjust);
#ifdef FB_DEBUG
    pPixmap->devPrivate.ptr = (void *) ((char *) pPixmap->devPrivate.ptr + paddedWidth);
    fbInitializeDrawable (&pPixmap->drawable);
#endif

#ifdef COMPOSITE
    pPixmap->screen_x = 0;
    pPixmap->screen_y = 0;
#endif

    return pPixmap;
}

AllocatePixmap() is implemented as:

/* callable by ddx */
PixmapPtr
AllocatePixmap(ScreenPtr pScreen, int pixDataSize)
{
    PixmapPtr pPixmap;
#ifdef PIXPRIV
    char *ptr;
    DevUnion *ppriv;
    unsigned *sizes;
    unsigned size;
    int i;

    if (pScreen->totalPixmapSize > ((size_t)-1) - pixDataSize)
	return NullPixmap;
    
    pPixmap = (PixmapPtr)xalloc(pScreen->totalPixmapSize + pixDataSize);
    if (!pPixmap)
	return NullPixmap;
    ppriv = (DevUnion *)(pPixmap + 1);
    pPixmap->devPrivates = ppriv;
    sizes = pScreen->PixmapPrivateSizes;
    ptr = (char *)(ppriv + pScreen->PixmapPrivateLen);
    for (i = pScreen->PixmapPrivateLen; --i >= 0; ppriv++, sizes++)
    {
        if ((size = *sizes) != 0)
        {
	    ppriv->ptr = (pointer)ptr;
	    ptr += size;
        }
        else
	    ppriv->ptr = (pointer)NULL;
    }
#else
    pPixmap = (PixmapPtr)xalloc(sizeof(PixmapRec) + pixDataSize);
#endif
    return pPixmap;
}

Given that pPixmap points at the start of PixmapRec the following fbCreatePixmapBpp() instruction points
pPixmap->devPrivate.ptr after PixmapRec at pixmap data.
    pPixmap->devPrivate.ptr = (pointer) ((char *)pPixmap + base + adjust);

pPixmap, the pointer to the pixmap created previously (of type PixmapPtr) is passed then to ModifyPixmapHeader(), which is actually miModifyPixmapHeader(), implemented as:

/* this plugs into pScreen->ModifyPixmapHeader */
Bool
miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind,
		     pPixData)
    PixmapPtr   pPixmap;
    int		width;
    int		height;
    int		depth;
    int		bitsPerPixel;
    int		devKind;
    pointer     pPixData;
{
    if (!pPixmap)
	return FALSE;

    /*
     * If all arguments are specified, reinitialize everything (including
     * validated state).
     */
    if ((width > 0) && (height > 0) && (depth > 0) && (bitsPerPixel > 0) &&
	(devKind > 0) && pPixData) {
	pPixmap->drawable.depth = depth;
	pPixmap->drawable.bitsPerPixel = bitsPerPixel;
	pPixmap->drawable.id = 0;
	pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
	pPixmap->drawable.x = 0;
	pPixmap->drawable.y = 0;
	pPixmap->drawable.width = width;
	pPixmap->drawable.height = height;
	pPixmap->devKind = devKind;
	pPixmap->refcnt = 1;
	pPixmap->devPrivate.ptr = pPixData;
    } else {
	/*
	 * Only modify specified fields, keeping all others intact.
	 */

	if (width > 0)
	    pPixmap->drawable.width = width;

	if (height > 0)
	    pPixmap->drawable.height = height;

	if (depth > 0)
	    pPixmap->drawable.depth = depth;

	if (bitsPerPixel > 0)
	    pPixmap->drawable.bitsPerPixel = bitsPerPixel;
	else if ((bitsPerPixel < 0) && (depth > 0))
	    pPixmap->drawable.bitsPerPixel = BitsPerPixel(depth);

	/*
	 * CAVEAT:  Non-SI DDXen may use devKind and devPrivate fields for
	 *          other purposes.
	 */
	if (devKind > 0)
	    pPixmap->devKind = devKind;
	else if ((devKind < 0) && ((width > 0) || (depth > 0)))
	    pPixmap->devKind = PixmapBytePad(pPixmap->drawable.width,
		pPixmap->drawable.depth);

	if (pPixData)
	    pPixmap->devPrivate.ptr = pPixData;
    }
    return TRUE;
}

Recall the comment of of miCreateScreenResources() "create a pixmap with no data, then redirect it to point to the screen". The routine that created the empty pixmap was (*pScreen->CreatePixmap) actually fbCreatePixmap() and the routine that (*pScreen->ModifyPixmapHeader), which is actually miModifyPixmapHeader() sets the address of the pixmap to the screen memory address is (*pScreen->ModifyPixmapHeader), which is actually miModifyPixmapHeader().

The address is passed as the last argument of (*pScreen->ModifyPixmapHeader) and as seen in miCreateScreenResources() this is pScrInitParms->pbits. This was set to pbits by miScreenDevPrivateInit() and pbits replaces the FBStart fbScreenInit(), which is the screen memory address. As we read in section 3.2.2.11: "Mga->FbStart is equal to pMga->FbBase since YDstOrg (the offset in bytes from video start to usable memory) is usually zero (see comment in MGAPreInit())".

The usage of the ModifyPixmapHeader() is also explained in the DESIGN document:

                                             Additionally, if an aper-
     ture used to access video memory is unmapped and remapped in this
     fashion, ChipEnterVT() will also need to notify the framebuffer
     layers of the aperture's new location in virtual memory.  This is
     done with a call to the screen's ModifyPixmapHeader() function, as
     follows

          (*pScreen->ModifyPixmapHeader)(pScrn->ppix,

                    -1, -1, -1, -1, -1, NewApertureAddress);

               where the ``ppix'' field in a ScrnInfoRec
               points to the pixmap used by the screen's
               SaveRestoreImage() function to hold the
               screen's contents while switched out.

We continue to section 3.2.2.13.

NOTES:

Purple code text assigns values to ScreenRec fields

REFERENCES:

How Video Cards Work
Backing Store Attribute
Distributed Multihead X design