/****************************************************************************
 * Rage 128 Chapter 7 sample code                                           *
 *                                                                          *
 * ov1creat.c - This module creates a "surface" for the overlay, which      *
 *              will hold the data that will be displayed using the         *
 *              overlay/scaler.                                             *
 *                                                                          *
 * Copyright (c) 1999 ATI Technologies Inc. All rights reserved.            *
 ****************************************************************************/
#include <math.h>
#include "overlay.h"

void CreateSurface (DWORD Width, DWORD Height, DWORD ScalerSourceFormat, DWORD Tiled, DWORD mem_offset, SURFACE *Surface)
{
    const ByteMemWordWidth  = 16;
    const ByteTileWidth     = 64;
    const ByteTileHeight    = 16;

    float BytesPerPixel;
    float UV_Subsampling;

    Surface->Base       = mem_offset;       /* Common to all branches of the function */

    switch(ScalerSourceFormat)
    {
         case SCALER_SOURCE_15BPP:
     case SCALER_SOURCE_16BPP:  BytesPerPixel = 2.0;
                    Surface->Pitch = (DWORD)(ceil (BytesPerPixel * (float)Width / (float)ByteMemWordWidth) * ByteMemWordWidth);
                    Surface->Height     = Height;
                    Surface->UBase      = 0;           /* Defaults for Non-Planer modes */
                    Surface->UPitch     = 0;
                    Surface->UHeight    = 0;
                    Surface->VBase      = 0;
                    Surface->VPitch     = 0;
                    Surface->VHeight    = 0;
                    break;
     case SCALER_SOURCE_32BPP:  BytesPerPixel = 4.0;
                    Surface->Pitch = (DWORD)(ceil (BytesPerPixel * (float)Width / (float)ByteMemWordWidth) * ByteMemWordWidth);
                    Surface->Height     = Height;
                    Surface->UBase      = 0;           /* Defaults for Non-Planer modes */
                    Surface->UPitch     = 0;
                    Surface->UHeight    = 0;
                    Surface->VBase      = 0;
                    Surface->VPitch     = 0;
                    Surface->VHeight    = 0;
                    break;
         case SCALER_SOURCE_YUV12:
         case SCALER_SOURCE_YUV9:   BytesPerPixel = 1.0;
                    if (ScalerSourceFormat == SCALER_SOURCE_YUV12)
                    {
                        UV_Subsampling = 2.0;
                    }
                        else /* SCALER_SOURCE_YUV9 */
                        {
                            UV_Subsampling = 4.0;
                        }

                    if (Tiled)
                    {
                        Surface->Pitch  = (DWORD)(ceil (BytesPerPixel * (float)Width  / ((float)ByteTileWidth * 2.0)) * ByteTileWidth * 2);
                        Surface->Height = (DWORD)(ceil ((float)Height / (float)ByteTileHeight) * ByteTileHeight);
                    }
                    else /* Non-Tiled */
                    {
                        Surface->Pitch =  (DWORD)(ceil (BytesPerPixel * (float)Width  / ((float)ByteMemWordWidth * 2.0)) * ByteMemWordWidth * 2);
                        Surface->Height     = Height;
                    }

                    Surface->UBase   = mem_offset + Surface->Pitch * Surface->Height + Surface->Pitch / 2;
                    Surface->UPitch  = Surface->Pitch;
                    Surface->UHeight = (DWORD)(ceil ((float)Height / UV_Subsampling / (float)ByteTileHeight) * ByteTileHeight);
                    Surface->VBase   = mem_offset + Surface->Pitch * Surface->Height;
                    Surface->VPitch  = Surface->Pitch;
                    Surface->VHeight = Surface->UHeight;
                    break;

    case SCALER_SOURCE_VYUY422:
    case SCALER_SOURCE_YVYU422: BytesPerPixel = 2.0;
                    Surface->Pitch = (DWORD)(ceil (BytesPerPixel * (float)Width / (float)ByteMemWordWidth) * ByteMemWordWidth);
                    Surface->Height     = Height;
                    Surface->UBase      = 0;           /* Defaults for Non-Planer modes */
                    Surface->UPitch     = 0;
                    Surface->UHeight    = 0;
                    Surface->VBase      = 0;
                    Surface->VPitch     = 0;
                    Surface->VHeight    = 0;
                    break;
    }

    /* Common to all branches of the function */
    Surface->ImageWidth = Width;
    Surface->ImageHeight = Height;
    Surface->SurfaceFormat = ScalerSourceFormat;
    Surface->TiledSurface = Tiled;

}

