SDL-1.2.14
[sdl_omap.git] / src / video / fbcon / SDL_fbriva.c
CommitLineData
e14743d1 1/*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2009 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
31static int FifoEmptyCount = 0;
32static int FifoFreeCount = 0;
33
34/* Wait for vertical retrace */
35static void WaitVBL(_THIS)
36{
37 volatile Uint8 *port = (Uint8 *)(mapped_io + PCIO_OFFSET + 0x3DA);
38
39 while ( (*port & 0x08) )
40 ;
41 while ( !(*port & 0x08) )
42 ;
43}
44static void 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}
51static void 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
59#if 0 /* Not yet implemented? */
60/* Sets video mem colorkey and accelerated blit function */
61static int SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key)
62{
63 return(0);
64}
65
66/* Sets per surface hardware alpha value */
67static int SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 value)
68{
69 return(0);
70}
71#endif /* Not yet implemented */
72
73static int FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color)
74{
75 int dstX, dstY;
76 int dstW, dstH;
77 RivaBitmap *Bitmap = (RivaBitmap *)(mapped_io + BITMAP_OFFSET);
78
79 /* Don't blit to the display surface when switched away */
80 if ( switched_away ) {
81 return -2; /* no hardware access */
82 }
83 if ( dst == this->screen ) {
84 SDL_mutexP(hw_lock);
85 }
86
87 /* Set up the X/Y base coordinates */
88 dstW = rect->w;
89 dstH = rect->h;
90 FB_dst_to_xy(this, dst, &dstX, &dstY);
91
92 /* Adjust for the current rectangle */
93 dstX += rect->x;
94 dstY += rect->y;
95
96 RIVA_FIFO_FREE(Bitmap, 1);
97 Bitmap->Color1A = color;
98
99 RIVA_FIFO_FREE(Bitmap, 2);
100 Bitmap->UnclippedRectangle[0].TopLeft = (dstX << 16) | dstY;
101 Bitmap->UnclippedRectangle[0].WidthHeight = (dstW << 16) | dstH;
102
103 FB_AddBusySurface(dst);
104
105 if ( dst == this->screen ) {
106 SDL_mutexV(hw_lock);
107 }
108 return(0);
109}
110
111static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
112 SDL_Surface *dst, SDL_Rect *dstrect)
113{
114 SDL_VideoDevice *this = current_video;
115 int srcX, srcY;
116 int dstX, dstY;
117 int dstW, dstH;
118 RivaScreenBlt *Blt = (RivaScreenBlt *)(mapped_io + BLT_OFFSET);
119
120 /* FIXME: For now, only blit to display surface */
121 if ( dst->pitch != SDL_VideoSurface->pitch ) {
122 return(src->map->sw_blit(src, srcrect, dst, dstrect));
123 }
124
125 /* Don't blit to the display surface when switched away */
126 if ( switched_away ) {
127 return -2; /* no hardware access */
128 }
129 if ( dst == this->screen ) {
130 SDL_mutexP(hw_lock);
131 }
132
133 /* Calculate source and destination base coordinates (in pixels) */
134 dstW = dstrect->w;
135 dstH = dstrect->h;
136 FB_dst_to_xy(this, src, &srcX, &srcY);
137 FB_dst_to_xy(this, dst, &dstX, &dstY);
138
139 /* Adjust for the current blit rectangles */
140 srcX += srcrect->x;
141 srcY += srcrect->y;
142 dstX += dstrect->x;
143 dstY += dstrect->y;
144
145 RIVA_FIFO_FREE(Blt, 3);
146 Blt->TopLeftSrc = (srcY << 16) | srcX;
147 Blt->TopLeftDst = (dstY << 16) | dstX;
148 Blt->WidthHeight = (dstH << 16) | dstW;
149
150 FB_AddBusySurface(src);
151 FB_AddBusySurface(dst);
152
153 if ( dst == this->screen ) {
154 SDL_mutexV(hw_lock);
155 }
156 return(0);
157}
158
159static int CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst)
160{
161 int accelerated;
162
163 /* Set initial acceleration on */
164 src->flags |= SDL_HWACCEL;
165
166 /* Set the surface attributes */
167 if ( (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
168 if ( ! this->info.blit_hw_A ) {
169 src->flags &= ~SDL_HWACCEL;
170 }
171 }
172 if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {
173 if ( ! this->info.blit_hw_CC ) {
174 src->flags &= ~SDL_HWACCEL;
175 }
176 }
177
178 /* Check to see if final surface blit is accelerated */
179 accelerated = !!(src->flags & SDL_HWACCEL);
180 if ( accelerated ) {
181 src->map->hw_blit = HWAccelBlit;
182 }
183 return(accelerated);
184}
185
186void FB_RivaAccel(_THIS, __u32 card)
187{
188 RivaRop *Rop = (RivaRop *)(mapped_io + ROP_OFFSET);
189
190 /* We have hardware accelerated surface functions */
191 this->CheckHWBlit = CheckHWBlit;
192 wait_vbl = WaitVBL;
193 switch (card) {
194 case FB_ACCEL_NV3:
195 wait_idle = NV3WaitIdle;
196 break;
197 case FB_ACCEL_NV4:
198 wait_idle = NV4WaitIdle;
199 break;
200 default:
201 /* Hmm... FIXME */
202 break;
203 }
204 FifoEmptyCount = Rop->FifoFree;
205
206 /* The Riva has an accelerated color fill */
207 this->info.blit_fill = 1;
208 this->FillHWRect = FillHWRect;
209
210 /* The Riva has accelerated normal and colorkey blits. */
211 this->info.blit_hw = 1;
212#if 0 /* Not yet implemented? */
213 this->info.blit_hw_CC = 1;
214 this->SetHWColorKey = SetHWColorKey;
215#endif
216
217#if 0 /* Not yet implemented? */
218 /* The Riva has an accelerated alpha blit */
219 this->info.blit_hw_A = 1;
220 this->SetHWAlpha = SetHWAlpha;
221#endif
222}