/****************************************************************************
 * Rage 128 Chapter 7 sample code                                           *
 *                                                                          *
 * ov1init.c - This module initializes the overlay descriptor.              *
 *                                                                          *
 * Copyright (c) 1999 ATI Technologies Inc. All rights reserved.            *
 ****************************************************************************/
#include "overlay.h"

#define UNINITIALIZED 0xffffffff
/* UNINITIALIZED values absolutely must be filled out before the overlay will work. */
/* Other values that are initialized to default values based on a most likely configuration */
/* of the graphic card, but will not work in many other configurations. */
/* Please make sure that this structure is correctly and completely filled out before */
/* calling the SetupOverlay routine. */

void R128_InitOverlayDescriptor (OVERLAY_DESCRIPTOR *OverlayDescriptor)
{

    int i;

    /* Bandwidth and other display mode info */
    /* ************************************* */
    /* These values that must be provided to determine available bandwidth (possibly obtained via CWDDE which queries the BIOS) */
    OverlayDescriptor->HTOTAL_InCharactersMinusOne = (DWORD) UNINITIALIZED;
    OverlayDescriptor->HDISP_InCharactersMinusOne = (DWORD) UNINITIALIZED;
    OverlayDescriptor->PrimaryPixelDepthInBytes = (DWORD) UNINITIALIZED;
    OverlayDescriptor->DisplayFIFOSizeInBytes = (DWORD) 64*16;      /* 64 Bytes by 16 entries. This is worst case. On the hairy edge, we may have to have reduce the size to free up space for the scaler in the HBlank */
    OverlayDescriptor->CRTCInterlaceEnable = (DWORD) UNINITIALIZED;
    OverlayDescriptor->PixelClock_VCLK_PeriodInPicoSec = (DWORD) UNINITIALIZED;     /* Because of genlock, the PixelClock will vary typically by several hundred ppm. Please provide the fastest pixel clock expected. */
    OverlayDescriptor->MemoryClock_XCLK_PeriodInPicoSec = (DWORD) UNINITIALIZED;    /* We expect to run some 64 bit wide memory banks at double XCLK. Do not confuse the external memory clock with the internal "XCLK". */
    OverlayDescriptor->ECP_DIV_ValueFromPLLRegs = (DWORD) UNINITIALIZED;
    OverlayDescriptor->MEM_CHECKBOARD = (DWORD) UNINITIALIZED;      /* Need to read this after BIOS sets up the chip. It is used to determine how tiled surfaces are stored in the frame buffer. */

    OverlayDescriptor->MissPenalty = 2;
    OverlayDescriptor->CyclesPerOctword = 1;
    OverlayDescriptor->MissAllignmentPenalty = (DWORD) 1;
    OverlayDescriptor->OpenPenalty = (DWORD) 3;
    OverlayDescriptor->WriteClosePenalty = (DWORD) 4;
    OverlayDescriptor->ReadClosePenalty = (DWORD) 3;
    OverlayDescriptor->BankChangePenalty = (DWORD) 3;
    OverlayDescriptor->RefreshCycleTime = (DWORD) 10;

    OverlayDescriptor->DISP_LINES_ARE_64BYTE_ALLIGNED = (DWORD) 0;
    OverlayDescriptor->CAN_GUARANTEE_NO_SUBPICTURE = (DWORD) 1;
    OverlayDescriptor->CAN_GUARANTEE_NO_VIDEO_CAPTURE = (DWORD) 0;
    OverlayDescriptor->CAN_GUARANTEE_ONLY_ONE_VIDEO_CAPTURE = (DWORD) 0;
    OverlayDescriptor->CAN_GUARANTEE_THIS_IS_RAGE128_REV_A = (DWORD) 1;

    /* Bandwidth Calculation and Result Interpretation */
    /* *********************************************** */
    OverlayDescriptor->BandwidthDirective = (DWORD) 1;
        /* 1 = BEST_EFFORT (Assume bandwidth info is good and do the best scaling possible with available bandwidth) */
        /* 2 = DETERMINE_HBLANK_NEEDED (Given the scaling ratios, MAX_LN_IN_PER_LN_OUT, and other info provided, work out the minimum CRTCHTotalInPixels needed) */
    OverlayDescriptor->NeededHTotal = (DWORD) UNINITIALIZED;
        /* If you set BandwidthDirective to DETERMINE_HBLANK_NEEDED then the scaler determines how large an HBlank is needed and returns "NeededHTotal". */
        /* It sets up the scaler assuming that the HTotal will be adjusted to meet it's needs. The DETERMINE_HBLANK_NEEDED directive should be used for testing only. */
    /* Basic Scaling Settings */
    /* *********************************************** */
    OverlayDescriptor->OVERLAY_ENABLE = (DWORD) 0;          /* Turns on the scaler. (Will also power up the scaler and subpicture clock.) */
    OverlayDescriptor->DOUBLE_BUFFER_REGS = (DWORD) 1;      /* Should always set to one except for test. */

    OverlayDescriptor->SURFACE_FORMAT = (DWORD) UNINITIALIZED;

    OverlayDescriptor->SrcHeight = (DWORD) UNINITIALIZED;
    OverlayDescriptor->SrcWidth = (DWORD) UNINITIALIZED;

    /* Out of bounds areas (negative values or values that exceed SrcHeight and SrcWidth) will be */
    /* replaced with black by hardware if possible. This can be used for DVD letterboxing for example. */

    OverlayDescriptor->PHYSICAL_SrcLeft = (double) UNINITIALIZED;
    OverlayDescriptor->PHYSICAL_SrcRight = (double) UNINITIALIZED;
    OverlayDescriptor->PHYSICAL_SrcTop = (double) UNINITIALIZED;
    OverlayDescriptor->PHYSICAL_SrcBottom = (double) UNINITIALIZED;

    /* Indicates the surface location on the screen for both video and subpicture */
    OverlayDescriptor->PHYSICAL_DestLeft = (DWORD) UNINITIALIZED;
    OverlayDescriptor->PHYSICAL_DestRight = (DWORD) UNINITIALIZED;
    OverlayDescriptor->PHYSICAL_DestTop = (DWORD) UNINITIALIZED;
    OverlayDescriptor->PHYSICAL_DestBottom = (DWORD) UNINITIALIZED;

    /* ****************************** */
    OverlayDescriptor->SurfaceIsTiled = (DWORD) UNINITIALIZED;

    OverlayDescriptor->SimpleBaseOffsetOfSurface = (DWORD) UNINITIALIZED;
    OverlayDescriptor->SimpleSurfacePitch = (DWORD) UNINITIALIZED;

    OverlayDescriptor->USE_DETAILED_SURFACE_DESCRIPTION = 0;
    for (i=0; i<6; i++)
    {
        OverlayDescriptor->BaseOffsetOfSurface[i] = (DWORD) UNINITIALIZED;
        OverlayDescriptor->SurfaceSpecificXOffset[i] = (DWORD) UNINITIALIZED;
        OverlayDescriptor->SurfaceSpecificYOffset[i] = (DWORD) UNINITIALIZED;
        OverlayDescriptor->PitchSelectOfSurface[i] = (DWORD) UNINITIALIZED;
    }
    for (i=0; i<2; i++)
    {
        OverlayDescriptor->SurfacePitch[i] = (DWORD) UNINITIALIZED;
    }
    /* ****************************** */

    /* Scaling Quality Controls */
    /* ************************ */
    OverlayDescriptor->SharpnessEffect = (DWORD) 0;
        /* A nominal value of ???? will result in the most accurate image resampling according to sampling theory. However, image quality is */
        /* subjectively evaluated, and sometimes the degree of sharpness depends on the type of video content. This parameter provides the */
        /* user with the freedom to further sharpen or dull the image. */

    /* Scaling Quality Overrides */
    /* ************************ */
        /* The scaler setup routine will automatically determine the best settings for a given display mode, and set of scaling parameters. */
        /* However, for test of demo purposes, you can force the scaler to make other choices. */
    OverlayDescriptor->P1_MAX_LN_IN_PER_LN_OUT = (DWORD) 0;
    OverlayDescriptor->P23_MAX_LN_IN_PER_LN_OUT = (DWORD) 0;        /* Used only for U and V planes in planer modes */
        /* Describes how many lines you are willing to allow the scaler to fetch per line out. */
        /* More lines means better downscaling, but also more bandwidth! If you set the BandwidthDirective */
        /* to BEST_EFFORT, then the scaler will use as many lines as possible, but it will not exceed OV0_P??_MAX_LN_IN_PER_LN_OUT. */
        /* If you can provide correct bandwidth info, then set these values to the max unless you want to reduce the scaling quality. */
    OverlayDescriptor->LOG_V_DECIMATION_FACT = (DWORD) 0;
    OverlayDescriptor->TWO_TAP_LINEAR_HORZ_FILT = (DWORD) 0;
    OverlayDescriptor->TWO_TAP_LINEAR_VERT_FILT = (DWORD) 0;
    OverlayDescriptor->HORZ_PICK_NEAREST = (DWORD) 0;           /* Use 0 unless source keying is needed */
    OverlayDescriptor->VERT_PICK_NEAREST = (DWORD) 0;           /* Use 0 unless source keying is needed */
    OverlayDescriptor->HC_COEF_ON_HORZ_Y = (DWORD) 0;
    OverlayDescriptor->HC_COEF_ON_HORZ_UV = (DWORD) 0;
    OverlayDescriptor->HC_COEF_ON_VERT_Y = (DWORD) 0;
    OverlayDescriptor->HC_COEF_ON_VERT_UV = (DWORD) 0;
    OverlayDescriptor->EMULATE_RAGE_PRO = (DWORD) 0;
        /* Will set OV0_P??_MAX_LN_IN_PER_LN_OUT to 1, */
        /* force two tap vertical filtering, */
        /* and drop pixels more aggressively when downscaling horizontally. */
    OverlayDescriptor->EMULATE_RIVA128 = (DWORD) 0;
        /* Will set OV0_P??_MAX_LN_IN_PER_LN_OUT to 1, */
        /* force TWO_TAP_LINEAR_HORZ_FILT and VERT_PICK_NEAREST filtering, */
        /* and drop pixels very aggressively when downscaling horizontally. */
    OverlayDescriptor->AllowPreDownScale = 0;

    /* Deinterlacing Control */
    /* ********************* */
        /* Note: The selection of bob or weave affects the vertical scaling done by hardware, recommend that deinterlacing and scaling */
        /* setup NOT be separate routines. */
    OverlayDescriptor->AutoFlipVideoProvider = (DWORD) 0;       /* VidPort0=0, VidPort1=1, Software=2 */
    OverlayDescriptor->IGNORE_REPEAT_FIELD = (DWORD) 0;

    /* Note: The following three registers may be hard coded in a future cost reduce revision of the Rage128 */
    OverlayDescriptor->DeinterlacePattern = (DWORD) 0; /* Up to 10 two bit values (max 20 bit value) */
                               /* Hardware remembers where the last three fields are. */
                               /* Each two bit value indicates what should be done with them. */
                               /* Each time a new field is delivered, the next two bit value is used. */
    OverlayDescriptor->DeinterlacePatternLenMinusOne = (DWORD) 0;   /* Number from 0 to 9 */
    OverlayDescriptor->DeinterlacePatternPointer = (DWORD) 0;       /* Number from 0 to 9 */

    OverlayDescriptor->ShiftFieldDown = (DWORD) 0;  /* 0 doesn't shift either field */
                            /* 1 to position even field below odd. */
                            /* 2 to position odd field below even. */
                            /* 3 shifts both fields down (not useful) */
    OverlayDescriptor->FIRST_LINE_EVEN = (DWORD) 0; /* When weaving, indicates that the first source line (pointed to by a base address register) */
                            /* Comes from an even field. */

    /* Submit Field */
    /* **************************************** */
    /* Software applications indicate to hardware that there is a new field for display using these parameters. */
    /* The plan is to have a separate call for this */
    OverlayDescriptor->There_Is_A_New_Field = (DWORD) 0; /* Tells the routine that a new field of source has been provided by software. */
    OverlayDescriptor->SurfaceBaseAddressNum = (DWORD) 0; /* Tells which "SurfaceBaseAddress" points to the new field of source. */
                                  /* If Planer, selects Y base. U is Y+1, V is Y+2, Y must be 0 or 4. */
    OverlayDescriptor->FieldIsOdd = (unsigned long) 0; /* Indicates that the new field of source is an odd field */
    OverlayDescriptor->RepeatField = (unsigned long) 0; /* Indicates a repeated field in an NTSC 3:2 Pull Down sequence of fields. */

    /* More generically, it indicates the beginning of a repeating pattern of even/odd fields so that the weaver can be aligned. */
    /* **************************************** */

    /* Colour and Effect Controls */
    /* ************************** */
    OverlayDescriptor->GAMMA_SEL = (DWORD) 0;
    OverlayDescriptor->Y2R_TEMP = (DWORD) 1; /* Always use 1 */
    OverlayDescriptor->INT_EMU = (DWORD) 0; /* Interlace emulation */
    OverlayDescriptor->BRIGHTNESS = (DWORD) 0;
    OverlayDescriptor->SATURATION_U = (DWORD) 0x10;
    OverlayDescriptor->SATURATION_V = (DWORD) 0x10;
    OverlayDescriptor->PIX_EXPAND = (DWORD) 1;
    /* Enables dynamic range expansion of RGB1555 and RGB565. (e.g. makes packed 1f,3f,1f value into ff,ff,ff instead of f8,fc,f8). Always use 1. */
    OverlayDescriptor->SIGNED_UV1 = (DWORD) 0;                      /* Changes interpretation of UV values in source image. PC's use 0, Apple's use 1 */
    OverlayDescriptor->COMCORE_SHIFT_UP_ONE = (DWORD) 0;
    /* Always use 0. Do not expose to any API. This feature is obsolete and we want to remove it in future chips. */
    /* Notify Phil Swan if anyone still needs this feature. */
    OverlayDescriptor->DIS_LIMIT = (DWORD) 0; /* Disables colour range limiters for test */
    OverlayDescriptor->SCALE_Y2R_DIS = (DWORD) 0; /* Disables colour conversion for test */

    /* Keying Controls */
    /* ************************** */
    OverlayDescriptor->VIDEO_KEY_CLR = (DWORD) 0;
    OverlayDescriptor->VIDEO_KEY_MSK = (DWORD) 0;
    OverlayDescriptor->VIDEO_KEY_FN = (DWORD) 0;

}
