src/video/fbcon/SDL_fbriva.c
author Edgar Simo <bobbens@gmail.com>
Sun, 06 Jul 2008 17:06:37 +0000
branchgsoc2008_force_feedback
changeset 2498 ab567bd667bf
parent 1895 c121d94672cb
child 2698 e1da92da346c
permissions -rw-r--r--
Fixed various mistakes in the doxygen.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2006 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 #include "SDL_video.h"
    25 #include "../SDL_blit.h"
    26 #include "SDL_fbriva.h"
    27 #include "riva_mmio.h"
    28 #include "riva_regs.h"
    29 
    30 
    31 static int FifoEmptyCount = 0;
    32 static int FifoFreeCount = 0;
    33 
    34 /* Wait for vertical retrace */
    35 static void
    36 WaitVBL(_THIS)
    37 {
    38     volatile Uint8 *port = (Uint8 *) (mapped_io + PCIO_OFFSET + 0x3DA);
    39 
    40     while ((*port & 0x08));
    41     while (!(*port & 0x08));
    42 }
    43 static void
    44 NV3WaitIdle(_THIS)
    45 {
    46     RivaRop *Rop = (RivaRop *) (mapped_io + ROP_OFFSET);
    47     while ((Rop->FifoFree < FifoEmptyCount) ||
    48            (*(mapped_io + PGRAPH_OFFSET + 0x000006B0) & 0x01));
    49 }
    50 static void
    51 NV4WaitIdle(_THIS)
    52 {
    53     RivaRop *Rop = (RivaRop *) (mapped_io + ROP_OFFSET);
    54     while ((Rop->FifoFree < FifoEmptyCount) ||
    55            (*(mapped_io + PGRAPH_OFFSET + 0x00000700) & 0x01));
    56 }
    57 
    58 #if 0                           /* Not yet implemented? */
    59 /* Sets video mem colorkey and accelerated blit function */
    60 static int
    61 SetHWColorKey(_THIS, SDL_Surface * surface, Uint32 key)
    62 {
    63     return (0);
    64 }
    65 
    66 /* Sets per surface hardware alpha value */
    67 static int
    68 SetHWAlpha(_THIS, SDL_Surface * surface, Uint8 value)
    69 {
    70     return (0);
    71 }
    72 #endif /* Not yet implemented */
    73 
    74 static int
    75 FillHWRect(_THIS, SDL_Surface * dst, SDL_Rect * rect, Uint32 color)
    76 {
    77     int dstX, dstY;
    78     int dstW, dstH;
    79     RivaBitmap *Bitmap = (RivaBitmap *) (mapped_io + BITMAP_OFFSET);
    80 
    81     /* Don't blit to the display surface when switched away */
    82     if (switched_away) {
    83         return -2;              /* no hardware access */
    84     }
    85     if (dst == this->screen) {
    86         SDL_mutexP(hw_lock);
    87     }
    88 
    89     /* Set up the X/Y base coordinates */
    90     dstW = rect->w;
    91     dstH = rect->h;
    92     FB_dst_to_xy(this, dst, &dstX, &dstY);
    93 
    94     /* Adjust for the current rectangle */
    95     dstX += rect->x;
    96     dstY += rect->y;
    97 
    98     RIVA_FIFO_FREE(Bitmap, 1);
    99     Bitmap->Color1A = color;
   100 
   101     RIVA_FIFO_FREE(Bitmap, 2);
   102     Bitmap->UnclippedRectangle[0].TopLeft = (dstX << 16) | dstY;
   103     Bitmap->UnclippedRectangle[0].WidthHeight = (dstW << 16) | dstH;
   104 
   105     FB_AddBusySurface(dst);
   106 
   107     if (dst == this->screen) {
   108         SDL_mutexV(hw_lock);
   109     }
   110     return (0);
   111 }
   112 
   113 static int
   114 HWAccelBlit(SDL_Surface * src, SDL_Rect * srcrect,
   115             SDL_Surface * dst, SDL_Rect * dstrect)
   116 {
   117     SDL_VideoDevice *this = current_video;
   118     int srcX, srcY;
   119     int dstX, dstY;
   120     int dstW, dstH;
   121     RivaScreenBlt *Blt = (RivaScreenBlt *) (mapped_io + BLT_OFFSET);
   122 
   123     /* FIXME: For now, only blit to display surface */
   124     if (dst->pitch != SDL_VideoSurface->pitch) {
   125         return (src->map->sw_blit(src, srcrect, dst, dstrect));
   126     }
   127 
   128     /* Don't blit to the display surface when switched away */
   129     if (switched_away) {
   130         return -2;              /* no hardware access */
   131     }
   132     if (dst == this->screen) {
   133         SDL_mutexP(hw_lock);
   134     }
   135 
   136     /* Calculate source and destination base coordinates (in pixels) */
   137     dstW = dstrect->w;
   138     dstH = dstrect->h;
   139     FB_dst_to_xy(this, src, &srcX, &srcY);
   140     FB_dst_to_xy(this, dst, &dstX, &dstY);
   141 
   142     /* Adjust for the current blit rectangles */
   143     srcX += srcrect->x;
   144     srcY += srcrect->y;
   145     dstX += dstrect->x;
   146     dstY += dstrect->y;
   147 
   148     RIVA_FIFO_FREE(Blt, 3);
   149     Blt->TopLeftSrc = (srcY << 16) | srcX;
   150     Blt->TopLeftDst = (dstY << 16) | dstX;
   151     Blt->WidthHeight = (dstH << 16) | dstW;
   152 
   153     FB_AddBusySurface(src);
   154     FB_AddBusySurface(dst);
   155 
   156     if (dst == this->screen) {
   157         SDL_mutexV(hw_lock);
   158     }
   159     return (0);
   160 }
   161 
   162 static int
   163 CheckHWBlit(_THIS, SDL_Surface * src, SDL_Surface * dst)
   164 {
   165     int accelerated;
   166 
   167     /* Set initial acceleration on */
   168     src->flags |= SDL_HWACCEL;
   169 
   170     /* Set the surface attributes */
   171     if ((src->flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
   172         if (!this->info.blit_hw_A) {
   173             src->flags &= ~SDL_HWACCEL;
   174         }
   175     }
   176     if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
   177         if (!this->info.blit_hw_CC) {
   178             src->flags &= ~SDL_HWACCEL;
   179         }
   180     }
   181 
   182     /* Check to see if final surface blit is accelerated */
   183     accelerated = !!(src->flags & SDL_HWACCEL);
   184     if (accelerated) {
   185         src->map->hw_blit = HWAccelBlit;
   186     }
   187     return (accelerated);
   188 }
   189 
   190 void
   191 FB_RivaAccel(_THIS, __u32 card)
   192 {
   193     RivaRop *Rop = (RivaRop *) (mapped_io + ROP_OFFSET);
   194 
   195     /* We have hardware accelerated surface functions */
   196     this->CheckHWBlit = CheckHWBlit;
   197     wait_vbl = WaitVBL;
   198     switch (card) {
   199     case FB_ACCEL_NV3:
   200         wait_idle = NV3WaitIdle;
   201         break;
   202     case FB_ACCEL_NV4:
   203         wait_idle = NV4WaitIdle;
   204         break;
   205     default:
   206         /* Hmm... FIXME */
   207         break;
   208     }
   209     FifoEmptyCount = Rop->FifoFree;
   210 
   211     /* The Riva has an accelerated color fill */
   212     this->info.blit_fill = 1;
   213     this->FillHWRect = FillHWRect;
   214 
   215     /* The Riva has accelerated normal and colorkey blits. */
   216     this->info.blit_hw = 1;
   217 #if 0                           /* Not yet implemented? */
   218     this->info.blit_hw_CC = 1;
   219     this->SetHWColorKey = SetHWColorKey;
   220 #endif
   221 
   222 #if 0                           /* Not yet implemented? */
   223     /* The Riva has an accelerated alpha blit */
   224     this->info.blit_hw_A = 1;
   225     this->SetHWAlpha = SetHWAlpha;
   226 #endif
   227 }
   228 
   229 /* vi: set ts=4 sw=4 expandtab: */