• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
WaitVBL(_THIS)35 static 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 }
NV3WaitIdle(_THIS)44 static 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 }
NV4WaitIdle(_THIS)51 static 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 */
61 static int SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key)
62 {
63 	return(0);
64 }
65 
66 /* Sets per surface hardware alpha value */
67 static int SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 value)
68 {
69 	return(0);
70 }
71 #endif /* Not yet implemented */
72 
FillHWRect(_THIS,SDL_Surface * dst,SDL_Rect * rect,Uint32 color)73 static 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 
HWAccelBlit(SDL_Surface * src,SDL_Rect * srcrect,SDL_Surface * dst,SDL_Rect * dstrect)111 static 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 
CheckHWBlit(_THIS,SDL_Surface * src,SDL_Surface * dst)159 static 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 
FB_RivaAccel(_THIS,__u32 card)186 void 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 }
223