This is the entry point in the driver for BitBlt. It handles the device-independent portions of BitBlt. It validates parameters, transforms coordinates, and handles error logging. When it has completed some setup, eddb_BitBlt looks at the raster operation and splits into one of several cases, such as a three-way raster operation, a raster operation involving the source and destination, a raster operation involving a pattern and the destination, or a raster operation involving the destination-only. The following is a simplified pseudocode for eddb_BitBlt:

eddb_BitBlt()
// check for stretch blt
if not COM_DEVICE
    if ArgCount == 4 and src_coords != dst_coords
        stretch_return_code = IsValidStretchRequest()

        //can the driver handle the stretch blt?
        if stretch_return_code != OK
            Perform call-back to the engine to do stretchblt

// at this point, eddb_BitBlt checks for a valid rop, and checks to see
// if the request is for correlation or drawing, etc.

if COM_CORRELATE
    if not eddg_ClipPickWindow()        // get correlation rectangles
        goto BITBLT_EXIT                //error!

//if the PM desktop is in the background and the destination is the
//display, disable drawing
if fXGADead and Destination is display
    COMMANDBITS = COMMANDBITS and not(COM_DRAW)

//convert target coordinates to device coordinates
TransformCoordinates()

//Examine the rop and determine which case it falls into

if source_is_required(rop)
    goto SOURCE_3WAY_COMMON
else
    goto PAT_DSTONLY_COMMON

SOURCE_3WAY_COMMON:
//handle all blts with a source, including blts involving source,
//pattern, and destination
if not(Stretching) //no need to setup if this is a stretchblt
    if source is a bit map
        convert handle to pointer and assign to AIxfer.pbmhSrc
    else //source is a device context handle
        convert handle to pointer to DC and assign to pdcSrc
        //get a pointer to the bit map defining the device
        AIxfer.pbmhsrc = pdcSrc->DCISelListEntry

Build rectangles defining the source and destination

//correlation involves determining if a pick is inside the area
//of the drawing operation.
if COM_CORRELATE
        perform correlation

//see if we need to draw
if not(COM_DRAW)
        goto BITBLT_EXIT

Calculate BitBlt dimensions and store in AIxfer.rcsTrg and
AIxfer.rcsSrc

if software_cursor
    calculate exclusion rectangle
    eddm_ExcludeCursor()

if pattern(rop)
    goto THREE_WAY_BLT    //there is a pattern involved
else
    goto SRC_DST_BLT      //no pattern involved

SRC_DST_BLT:
if palette mapping is required
    create palette mapping
    if the source is cached
        evict source bit map from the cache

//is the destination the display?
if AIxfer.pbmhDest == DirectListEntry
    SetDrawModeHard    //drawing to the display
else
    SetDrawModeSoft    //drawing to a bit map

//check for monochrome expansion
if mono(source) and not(mono(destination))
    //source is 1 bpp and destination isn't, so this is a monochrome
    //expansion blt

    setup foreground and background colors in Shadow8514Regs
    if destination is cached
        evict destination from the cache

else
    //both source and destination are in the same format
    //or source is color and destination is monochrome
    if source and destination are the same bit map
        if source and destination overlap
            determine direction in which to blt
            note that clipping rectangles need to be re-ordered
            store blt directions in pixelop
    else if source is color and destination is monochrome
        AIxfer.pbmhSrc = convert_colour_to_mono

Set source and mix in Shadow8514Regs
TransferShadowRegisters
SPad.BltFunction = either eddf_SrcDestBlt or eddh_SrcDestBlt

if src and dest are system memory or src and dest are
display
    PixBltThroughClips
else
    PixBltThroughClipsViaPhunk

if destination is cached
    evict destination from the cache

goto BITBLT_EXIT

THREE_WAY_BLT:
//source, pattern, and destination are involved in this rop

Save a copy of AIxfer.pbmhDest
Save a copy of AIxfer.pbmhSrc
Setup the pattern
Save a copy of the source & target rectangles

if source bit map == destination bit map
    if source and destination overlap
        determine order for clipping regions
        determine blt directions
else if source is monochrome and destination is color
    get foreground and background colors for mono bit map
else if destination is monochrome and source is color
    source = convert_colour_to_mono(source)

if bit 7 of the rop is set
    rop = 0ffh - rop
    calculate starting blt instruction
    add trailing "not" to last blt instruction
else
    get pointer to starting instruction

if Blt3WayBuffer[rop].CreateNew == TRUE
    allocate a temporary bit map to hold intermediate results

instruction_count = Blt3WayBuffer[rop].Size

while (instruction_count > 0)
    if Instruction->Destination == BT_DEST
        fThreeWayBlt = False    //clip the destination
        set up destination map in AIxfer
    else if Instruction->Destination == BT_WORK
        fThreeWayBlt = True     //don't clip the destination
        set up work map in AIxfer

    if Instruction->Source == BT_PAT
        set up the pattern in AIxfer
        if destination is the display
            SetDrawModeHard()
        else
            SetDrawModeSoft()
       else
        if Instruction->Source == BT_DEST
            set AIxfer source to destination bit map
        else if Instruction->Source == BT_WORK
            set AIxfer source to temporary bit map
        else if Instruction->Source == BT_SRC
            set AIxfer source to actual source bit map
        else
            no source, so do nothing!

    if destination is the display
        SetDrawModeHard()
    else
        SetDrawModeSoft()

    set up palette mapping if needed

    set up foreground and background colors and mixes based on if
    the blt is expanding from monochrome to color.

    TransferShadowRegisters()

    if src and dest are system memory or src and dest are display
        PixBltThroughClips
    else
        PixBltThroughClipsViaPhunk

    Instruction = next(Instruction)
    instruction_count = instruction_count - 1

fThreeWayWorkBlt = False

if the original rop >= 0x80
    remove trailing "not" from last Instruction

goto BITBLT_EXIT

PAT_DSTONLY_COMMON:
 //more of the same....

PAT_DST_BLT:
//not shown lest the pseudocode become as complicated as the
original

DST_ONLY_BLT:
//ditto


BITBLT_EXIT:
//end of BitBlt

Blting from source to destination involves several cases. First, there is the possibility that a palette mapping will be needed. (Palette mapping is necessary when the source and destination use differing palettes. Refer to eddb_CreatePalMapping in the EDDBPHNK.C file for details.) If the source is monochrome and the destination is not, the color_0 and Shadow8514Regs.color_1 fields must be set up. Finally, if both the source and destination are in system memory, or both are in VRAM, PixBltThroughClips is called to perform the blt. Otherwise, PixBltThroughClipsViaPhunk is called. The Phunk is always used when copying to or from system memory to VRAM. Using bus mastering via the Phunk was an optimization in the XGA driver, because copying to or from the Phunk to VRAM was fast. For the S3 driver, the Phunk is still useful if the source must be changed to a different format or if it must be stretched.

THREE_WAY_BLT involves a raster operation, a pattern, a source, and a destination. The key to understanding three-way blts is that they are interpreted. The blt interpreter breaks the raster operation down into a series of two-way blt operations that can be performed in either hardware or software. The following are examples of data structures:

// eddbtypt.h

typedef struct
{
    BYTE    Source;
    BYTE    Destination;
    BYTE    Mix;
    SHORT   BltFunction ;
} BltInst;
typedef BltInst NEAR * pBltInst;

typedef struct
{
    BYTE       CreateNew;
    BYTE       Size;
    pBltInst   Instruction;
} BltBuffEntry;
typedef BltBuffEntry NEAR * pBltBuffEntry;

In the EDDBDATA.C file, there is a large array called Blt3WayInsts, which is an array of BltInst structures. Each BltInst in the array is one step in the construction of a three-way BitBlt. BltInst.Source lists the source for this stage of the blt. Likewise, BltInst.Destination is the destination. BltInst.Source can have the following values:

ÚÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄ¿
³BT_DEST     ³0    ³Use the     ³
³            ³     ³destination ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄ´
³BT_WORK     ³1    ³Use the     ³
³            ³     ³temporary   ³
³            ³     ³work buffer ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄ´
³BT_SRC      ³2    ³Use the     ³
³            ³     ³source      ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄ´
³BT_PAT      ³3    ³Use the     ³
³            ³     ³pattern     ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄ´
³BT_NONE     ³4    ³Use none or ³
³            ³     ³the same as ³
³            ³     ³last time   ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÙ

BltInst.Destination can have as a value of either BT_DEST, BT_WORK, or BT_SRC. (BT_SRC implies no destination or specifies the use of the same destination as last time.)

The Mix field holds the hardware mix to use (XOR, OR, AND, COPY, and so forth), and the BltFunction field holds an index into the pDrawFunctionsTable. BltFunction selects which of three types of blt this instruction is to perform, such as a blt with a source and destination, a pattern blt, or a destination-only blt. For example, the following entry uses the source as the source for this step, uses the destination as the destination, uses a raster operation of (not source) and (not destination), and uses either eddf_SrcDestBlt or eddh_SrcDestBlt to perform this step. In effect, each entry in Blt3WayInsts is an instruction, with BltFunction and Mix forming the operation code.

BT_SRC, BT_DEST, HWMIX_NOTSOURCE_AND_NOTDEST,
index_SrcDestBlt,

Blt3WayBuffer is composed of structures of type BltBuffEntry. The CreateNew field of this structure is a Boolean value. When it is set to TRUE, a temporary buffer must be created for use during the blt. The Size field is the number of instructions it will take to perform this blt, (each instruction is a single entry in Blt3WayInsts), and Instruction field is a pointer to the first entry in Blt3WayInsts used for this blt.

Only raster operations from 0 to 7f hex are encoded this way. If the raster operation for the blt is greater than 80 hex, it is changed to the corresponding raster operation that is less than 80 hex, and a "not" operation is added to the final instruction for the blt. Performing the blt sets up the source and destination bit maps in AIxfer, and then calls either PixBltThroughClipsViaPhunk or PixBltThroughClips. When this has been completed, the next instruction in the blt is taken, and the cycle is repeated until no instructions remain.

The fThreeWayWorkBlt flag is true when the temporary bit map is being used as the destination for the blt. This flag exists so the PixBlt routines will not clip the work bit map against any clipping rectangles. It is necessary to avoid clipping the work bit map because it is an intermediate result, while the clipping rectangles refer to the destination bit map.

The pseudocode for pattern blts and destination-only blts generally follows a similar pattern to blts that involve a source and destination.


[Back: BitBlt - The Top Level Routines]
[Next: PixBltThroughClipsViaPhunk (PIXBLT.C) and PixBltThroughClips (PIXBLT.C)]