src/video/fbcon/SDL_fb3dfx.c
author Ozkan Sezer <sezeroz@gmail.com>
Sat, 14 Sep 2019 17:00:50 +0300
branchSDL-1.2
changeset 13077 cd46eb772bee
parent 6227 e11fd9609d10
permissions -rw-r--r--
make SDL_qsort.c to actually link (missing SDL_stdinc.h include)

also sync its comments with version 1.15 from mainstream
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2012 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_fb3dfx.h"
    27 #include "3dfx_mmio.h"
    28 
    29 
    30 /* Wait for vertical retrace */
    31 static void WaitVBL(_THIS)
    32 {
    33 	/* find start of retrace */
    34 	tdfx_waitidle();
    35 	while( (tdfx_in32(TDFX_STATUS) & STATUS_RETRACE) == STATUS_RETRACE )
    36 		;
    37 	/* wait until we're past the start */
    38 	while( (tdfx_in32(TDFX_STATUS) & STATUS_RETRACE) == 0 )
    39 		; 
    40 }
    41 static void WaitIdle(_THIS)
    42 {
    43 	tdfx_waitidle();
    44 }
    45 
    46 /* Sets video mem colorkey and accelerated blit function */
    47 static int SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key)
    48 {
    49 	return(0);
    50 }
    51 
    52 static int FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color)
    53 {
    54 	int bpp;
    55 	Uint32 dst_base;
    56 	Uint32 format;
    57 	int dstX, dstY;
    58 
    59 	/* Don't blit to the display surface when switched away */
    60 	if ( switched_away ) {
    61 		return -2; /* no hardware access */
    62 	}
    63 	if ( dst == this->screen ) {
    64 		SDL_mutexP(hw_lock);
    65 	}
    66 
    67 	/* Set the destination pixel format */
    68 	dst_base = ((char *)dst->pixels - mapped_mem);
    69 	bpp = dst->format->BitsPerPixel;
    70 	format = dst->pitch | ((bpp+((bpp==8) ? 0 : 8)) << 13);
    71 
    72 	/* Calculate source and destination base coordinates */
    73 	dstX = rect->x;
    74 	dstY = rect->y;
    75 
    76 	/* Execute the fill command */
    77 	tdfx_wait(6);
    78 	tdfx_out32(DSTBASE, dst_base);
    79 	tdfx_out32(DSTFORMAT, format);
    80 	tdfx_out32(COLORFORE, color);
    81 	tdfx_out32(COMMAND_2D, COMMAND_2D_FILLRECT);
    82 	tdfx_out32(DSTSIZE, rect->w | (rect->h << 16));
    83 	tdfx_out32(LAUNCH_2D, dstX | (dstY << 16));
    84 
    85 	FB_AddBusySurface(dst);
    86 
    87 	if ( dst == this->screen ) {
    88 		SDL_mutexV(hw_lock);
    89 	}
    90 	return(0);
    91 }
    92 
    93 static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
    94                        SDL_Surface *dst, SDL_Rect *dstrect)
    95 {
    96 	SDL_VideoDevice *this = current_video;
    97 	int bpp;
    98 	Uint32 src_format;
    99 	Uint32 src_base;
   100 	Uint32 dst_base;
   101 	int srcX, srcY;
   102 	int dstX, dstY;
   103 	Uint32 blitop;
   104 	Uint32 use_colorkey;
   105 
   106 	/* Don't blit to the display surface when switched away */
   107 	if ( switched_away ) {
   108 		return -2; /* no hardware access */
   109 	}
   110 	if ( dst == this->screen ) {
   111 		SDL_mutexP(hw_lock);
   112 	}
   113 
   114 	/* Set the source and destination pixel format */
   115 	src_base = ((char *)src->pixels - mapped_mem);
   116 	bpp = src->format->BitsPerPixel;
   117 	src_format = src->pitch | ((bpp+((bpp==8) ? 0 : 8)) << 13);
   118 	dst_base = ((char *)dst->pixels - mapped_mem);
   119 	bpp = dst->format->BitsPerPixel;
   120 
   121 	srcX = srcrect->x;
   122 	srcY = srcrect->y;
   123 	dstX = dstrect->x;
   124 	dstY = dstrect->y;
   125 
   126 	/* Assemble the blit operation */
   127 	blitop = COMMAND_2D_BITBLT | (0xCC << 24);
   128 	if ( srcX <= dstX ) {
   129 		blitop |= BIT(14);
   130 		srcX += (dstrect->w - 1);
   131 		dstX += (dstrect->w - 1);
   132 	}
   133 	if ( srcY <= dstY ) {
   134 		blitop |= BIT(15);
   135 		srcY += (dstrect->h - 1);
   136 		dstY += (dstrect->h - 1);
   137 	}
   138 
   139 	/* Perform the blit! */
   140 	if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {
   141     		tdfx_wait(3);
   142     		tdfx_out32(SRCCOLORKEYMIN, src->format->colorkey);
   143     		tdfx_out32(SRCCOLORKEYMAX, src->format->colorkey);
   144     		tdfx_out32(ROP_2D, 0xAA00);
   145 		use_colorkey = 1;
   146 	} else {
   147 		use_colorkey = 0;
   148 	}
   149 	tdfx_wait(9);
   150 	tdfx_out32(SRCBASE, (Uint32)src_base);
   151 	tdfx_out32(SRCFORMAT, src_format);
   152 	tdfx_out32(DSTBASE, (Uint32)dst_base);
   153 	tdfx_out32(DSTFORMAT, src_format);
   154 	tdfx_out32(COMMAND_2D, blitop);
   155 	tdfx_out32(COMMANDEXTRA_2D, use_colorkey);
   156 	tdfx_out32(DSTSIZE, dstrect->w | (dstrect->h << 16));
   157 	tdfx_out32(DSTXY, dstX | (dstY << 16));
   158 	tdfx_out32(LAUNCH_2D, srcX | (srcY << 16));
   159 
   160 	FB_AddBusySurface(src);
   161 	FB_AddBusySurface(dst);
   162 
   163 	if ( dst == this->screen ) {
   164 		SDL_mutexV(hw_lock);
   165 	}
   166 	return(0);
   167 }
   168 
   169 static int CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst)
   170 {
   171 	int accelerated;
   172 
   173 	/* Set initial acceleration on */
   174 	src->flags |= SDL_HWACCEL;
   175 
   176 	/* Set the surface attributes */
   177 	if ( (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
   178 		if ( ! this->info.blit_hw_A ) {
   179 			src->flags &= ~SDL_HWACCEL;
   180 		}
   181 	}
   182 	if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {
   183 		if ( ! this->info.blit_hw_CC ) {
   184 			src->flags &= ~SDL_HWACCEL;
   185 		}
   186 	}
   187 
   188 	/* Check to see if final surface blit is accelerated */
   189 	accelerated = !!(src->flags & SDL_HWACCEL);
   190 	if ( accelerated ) {
   191 		src->map->hw_blit = HWAccelBlit;
   192 	}
   193 	return(accelerated);
   194 }
   195 
   196 void FB_3DfxAccel(_THIS, __u32 card)
   197 {
   198 	/* We have hardware accelerated surface functions */
   199 	this->CheckHWBlit = CheckHWBlit;
   200 	wait_vbl = WaitVBL;
   201 	wait_idle = WaitIdle;
   202 
   203 	/* Reset the 3Dfx controller */
   204 	tdfx_out32(BRESERROR0, 0);
   205 	tdfx_out32(BRESERROR1, 0);
   206 
   207 	/* The 3Dfx has an accelerated color fill */
   208 	this->info.blit_fill = 1;
   209 	this->FillHWRect = FillHWRect;
   210 
   211 	/* The 3Dfx has accelerated normal and colorkey blits */
   212 	this->info.blit_hw = 1;
   213 	this->info.blit_hw_CC = 1;
   214 	this->SetHWColorKey = SetHWColorKey;
   215 }