updated SVGA sources from Mesa 3.2
[mesa.git] / src / mesa / drivers / svga / svgamesa.c
1 /* $Id: svgamesa.c,v 1.2 2000/01/22 20:08:36 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.2
6 * Copyright (C) 1995-2000 Brian Paul
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the Free
20 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23
24 /*
25 * SVGA driver for Mesa.
26 * Original author: Brian Paul
27 * Additional authors: Slawomir Szczyrba <steev@hot.pl> (Mesa 3.2)
28 */
29
30
31 #ifdef HAVE_CONFIG_H
32 #include "conf.h"
33 #endif
34
35 #ifdef SVGA
36
37 #ifdef PC_HEADER
38 #include "all.h"
39 #else
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <vga.h>
43 #include "GL/svgamesa.h"
44 #include "context.h"
45 #include "matrix.h"
46 #include "types.h"
47 #include <string.h>
48 #endif
49
50 #include "svgapix.h"
51 #include "svgamesa8.h"
52 #include "svgamesa15.h"
53 #include "svgamesa16.h"
54 #include "svgamesa24.h"
55 #include "svgamesa32.h"
56
57 struct svga_buffer SVGABuffer;
58 vga_modeinfo * SVGAInfo;
59 SVGAMesaContext SVGAMesa; /* the current context */
60
61 #ifdef SVGA_DEBUG
62
63 #include <sys/types.h>
64 #include <signal.h>
65
66 FILE * logfile;
67 char cbuf[1024]={0};
68
69 void SVGAlog(char * what)
70 {
71 logfile=fopen("svgamesa.log","a");
72 if (!logfile) return;
73 fprintf(logfile,"%s\n",what);
74 fclose(logfile);
75 }
76 #endif
77
78 /**********************************************************************/
79 /***** Init stuff... *****/
80 /**********************************************************************/
81
82 int SVGAMesaInit( int GraphMode )
83 {
84 vga_init();
85 if (!vga_hasmode(GraphMode))
86 {
87 fprintf(stderr,"GraphMode %d unavailable...",GraphMode);
88 #ifdef SVGA_DEBUG
89 SVGAlog("SVGAMesaInit: invalid GraphMode (doesn't exist)");
90 #endif
91 return(1);
92 }
93 SVGAInfo=vga_getmodeinfo(GraphMode);
94 if (SVGAInfo->flags & IS_MODEX)
95 {
96 fprintf(stderr,"ModeX not implemented...");
97 #ifdef SVGA_DEBUG
98 SVGAlog("SVGAMesaInit: invalid GraphMode (ModeX)");
99 #endif
100 return(2);
101 }
102 if (!SVGAInfo->bytesperpixel)
103 {
104 fprintf(stderr,"1 / 4 bit color not implemented...");
105 #ifdef SVGA_DEBUG
106 SVGAlog("SVGAMesaInit: invalid GraphMode (1 or 4 bit)");
107 #endif
108 return(3);
109 }
110 switch (SVGAInfo->colors) {
111 case 256: SVGABuffer.Depth = 8; break;
112 case 32768: SVGABuffer.Depth = 15; break;
113 case 65536: SVGABuffer.Depth = 16; break;
114 default: SVGABuffer.Depth = SVGAInfo->bytesperpixel<<3; break;
115 }
116 SVGABuffer.BufferSize=SVGAInfo->linewidth*SVGAInfo->height;
117 #ifdef SVGA_DEBUG
118 sprintf(cbuf,"SVGAMesaInit: double buffer info.\n" \
119 " depth : %d\n" \
120 " mode : %d\n" \
121 " width : %d\n" \
122 " height : %d\n" \
123 " bufsize: %d\n", \
124 SVGABuffer.Depth,GraphMode,SVGAInfo->linewidth, \
125 SVGAInfo->height,SVGABuffer.BufferSize);
126 SVGAlog(cbuf);
127 #endif
128 SVGABuffer.FrontBuffer=(void*)malloc(SVGABuffer.BufferSize + 4);
129 if (!SVGABuffer.FrontBuffer) {
130 {
131 fprintf(stderr,"Not enough RAM for FRONT_LEFT_BUFFER...");
132 #ifdef SVGA_DEBUG
133 SVGAlog("SVGAMesaInit: Not enough RAM (front buffer)");
134 #endif
135 return(4);
136 }
137 }
138 #ifdef SVGA_DEBUG
139 sprintf(cbuf,"SVGAMesaInit: FrontBuffer - %p",SVGABuffer.FrontBuffer);
140 SVGAlog(cbuf);
141 #endif
142 SVGABuffer.BackBuffer=(void*)malloc(SVGABuffer.BufferSize + 4);
143 if (!SVGABuffer.BackBuffer) {
144 {
145 free(SVGABuffer.FrontBuffer);
146 fprintf(stderr,"Not enough RAM for BACK_LEFT_BUFFER...");
147 #ifdef SVGA_DEBUG
148 SVGAlog("SVGAMesaInit: Not enough RAM (back buffer)");
149 #endif
150 return(5);
151 }
152 }
153 #ifdef SVGA_DEBUG
154 sprintf(cbuf,"SVGAMesaInit: BackBuffer - %p",SVGABuffer.BackBuffer);
155 SVGAlog(cbuf);
156 #endif
157
158 vga_setmode(GraphMode);
159 SVGABuffer.VideoRam=vga_getgraphmem();
160 #ifdef SVGA_DEBUG
161 sprintf(cbuf,"SVGAMesaInit: VRAM - %p",SVGABuffer.VideoRam);
162 SVGAlog(cbuf);
163 sprintf(cbuf,"SVGAMesaInit: done. (Mode %d)",GraphMode);
164 SVGAlog(cbuf);
165 #endif
166 return 0;
167 }
168
169 int SVGAMesaClose( void )
170 {
171 vga_setmode(TEXT);
172 free(SVGABuffer.FrontBuffer);
173 free(SVGABuffer.BackBuffer);
174 return 0;
175 }
176
177 void SVGAMesaSetCI(int ndx, GLubyte red, GLubyte green, GLubyte blue)
178 {
179 if (ndx<256) vga_setpalette(ndx, red>>2, green>>2, blue>>2);
180 }
181
182 /**********************************************************************/
183 /***** Miscellaneous functions *****/
184 /**********************************************************************/
185
186 static void copy_buffer( GLubyte * buffer) {
187 int size = SVGABuffer.BufferSize, page = 0;
188
189 #ifdef SVGA_DEBUG
190 sprintf(cbuf,"copy_buffer: copy %p to %p",buffer,SVGABuffer.VideoRam);
191 SVGAlog(cbuf);
192 #endif
193
194 while(size>0) {
195 vga_setpage(page++);
196 if (size>>16) {
197 memcpy(SVGABuffer.VideoRam,buffer,0x10000);
198 buffer+=0x10000;
199 }else{
200 memcpy(SVGABuffer.VideoRam,buffer,size & 0xffff);
201 }
202 size-=0xffff;
203 }
204 }
205
206 static void get_buffer_size( GLcontext *ctx, GLuint *width, GLuint *height )
207 {
208 *width = SVGAMesa->width = vga_getxdim();
209 *height = SVGAMesa->height = vga_getydim();
210 }
211
212 static GLboolean set_buffer( GLcontext *ctx, GLenum buffer )
213 {
214 void * tmpptr;
215
216 if (buffer == GL_FRONT_LEFT)
217 {
218 /* vga_waitretrace(); */
219 copy_buffer(SVGABuffer.FrontBuffer);
220 tmpptr=SVGABuffer.BackBuffer;
221 SVGABuffer.BackBuffer=SVGABuffer.FrontBuffer;
222 SVGABuffer.FrontBuffer=tmpptr;
223 return GL_TRUE;
224 }
225 else if (buffer == GL_BACK_LEFT)
226 {
227 /* vga_waitretrace(); */
228 copy_buffer(SVGABuffer.BackBuffer);
229 return GL_TRUE;
230 }
231 else
232 return GL_FALSE;
233 }
234
235 /**********************************************************************/
236 /***** *****/
237 /**********************************************************************/
238
239 static void svgamesa_update_state( GLcontext *ctx )
240 {
241 /* Initialize all the pointers in the DD struct. Do this whenever */
242 /* a new context is made current or we change buffers via set_buffer! */
243
244 ctx->Driver.UpdateState = svgamesa_update_state;
245
246 ctx->Driver.SetBuffer = set_buffer;
247 ctx->Driver.GetBufferSize = get_buffer_size;
248
249 ctx->Driver.PointsFunc = NULL;
250 ctx->Driver.LineFunc = NULL;
251 ctx->Driver.TriangleFunc = NULL;
252
253 switch (SVGABuffer.Depth) {
254 case 8: ctx->Driver.ClearIndex = __clear_index8;
255 ctx->Driver.Clear = __clear8;
256 ctx->Driver.Index = __set_index8;
257
258 ctx->Driver.ReadCI32Span = __read_ci32_span8;
259 ctx->Driver.ReadCI32Pixels = __read_ci32_pixels8;
260 ctx->Driver.WriteCI8Span = __write_ci8_span8;
261 ctx->Driver.WriteCI32Span = __write_ci32_span8;
262 ctx->Driver.WriteCI32Pixels = __write_ci32_pixels8;
263 ctx->Driver.WriteMonoCISpan = __write_mono_ci_span8;
264 ctx->Driver.WriteMonoCIPixels = __write_mono_ci_pixels8;
265 #ifdef SVGA_DEBUG
266 SVGAlog("SVGAUpdateState: 8 bit mode.");
267 #endif
268
269 break;
270 case 15: ctx->Driver.ClearColor = __clear_color15;
271 ctx->Driver.Clear = __clear15;
272 ctx->Driver.Color = __set_color15;
273
274 ctx->Driver.ReadRGBASpan = __read_rgba_span15;
275 ctx->Driver.ReadRGBAPixels = __read_rgba_pixels15;
276 ctx->Driver.WriteRGBASpan = __write_rgba_span15;
277 ctx->Driver.WriteRGBAPixels = __write_rgba_pixels15;
278 ctx->Driver.WriteMonoRGBASpan = __write_mono_rgba_span15;
279 ctx->Driver.WriteMonoRGBAPixels = __write_mono_rgba_pixels15;
280 #ifdef SVGA_DEBUG
281 SVGAlog("SVGAUpdateState: 15 bit mode.");
282 #endif
283 break;
284 case 16: ctx->Driver.ClearColor = __clear_color16;
285 ctx->Driver.Clear = __clear16;
286 ctx->Driver.Color = __set_color16;
287
288 ctx->Driver.ReadRGBASpan = __read_rgba_span16;
289 ctx->Driver.ReadRGBAPixels = __read_rgba_pixels16;
290 ctx->Driver.WriteRGBASpan = __write_rgba_span16;
291 ctx->Driver.WriteRGBAPixels = __write_rgba_pixels16;
292 ctx->Driver.WriteMonoRGBASpan = __write_mono_rgba_span16;
293 ctx->Driver.WriteMonoRGBAPixels = __write_mono_rgba_pixels16;
294 break;
295 #ifdef SVGA_DEBUG
296 SVGAlog("SVGAUpdateState: 16 bit mode.");
297 #endif
298 case 24: ctx->Driver.ClearColor = __clear_color24;
299 ctx->Driver.Clear = __clear24;
300 ctx->Driver.Color = __set_color24;
301
302 ctx->Driver.ReadRGBASpan = __read_rgba_span24;
303 ctx->Driver.ReadRGBAPixels = __read_rgba_pixels24;
304 ctx->Driver.WriteRGBASpan = __write_rgba_span24;
305 ctx->Driver.WriteRGBAPixels = __write_rgba_pixels24;
306 ctx->Driver.WriteMonoRGBASpan = __write_mono_rgba_span24;
307 ctx->Driver.WriteMonoRGBAPixels = __write_mono_rgba_pixels24;
308 break;
309 #ifdef SVGA_DEBUG
310 SVGAlog("SVGAUpdateState: 32 bit mode.");
311 #endif
312 case 32: ctx->Driver.ClearColor = __clear_color32;
313 ctx->Driver.Clear = __clear32;
314 ctx->Driver.Color = __set_color32;
315
316 ctx->Driver.ReadRGBASpan = __read_rgba_span32;
317 ctx->Driver.ReadRGBAPixels = __read_rgba_pixels32;
318 ctx->Driver.WriteRGBASpan = __write_rgba_span32;
319 ctx->Driver.WriteRGBAPixels = __write_rgba_pixels32;
320 ctx->Driver.WriteMonoRGBASpan = __write_mono_rgba_span32;
321 ctx->Driver.WriteMonoRGBAPixels = __write_mono_rgba_pixels32;
322 }
323 }
324
325 /*
326 * Create a new VGA/Mesa context and return a handle to it.
327 */
328 SVGAMesaContext SVGAMesaCreateContext( GLboolean doubleBuffer )
329 {
330 SVGAMesaContext ctx;
331 #ifndef DEV
332 GLboolean rgb_flag;
333 GLfloat redscale, greenscale, bluescale, alphascale;
334 GLboolean alpha_flag = GL_FALSE;
335 GLint index_bits;
336 GLint redbits, greenbits, bluebits, alphabits;
337 /* determine if we're in RGB or color index mode */
338 if ((SVGABuffer.Depth==32) || (SVGABuffer.Depth==24)) {
339 rgb_flag = GL_TRUE;
340 redscale = greenscale = bluescale = alphascale = 255.0;
341 redbits = greenbits = bluebits = 8;
342 alphabits = 0;
343 index_bits = 0;
344 }
345 else if (SVGABuffer.Depth==8) {
346 rgb_flag = GL_FALSE;
347 redscale = greenscale = bluescale = alphascale = 0.0;
348 redbits = greenbits = bluebits = alphabits = 0;
349 index_bits = 8;
350 }
351 else if (SVGABuffer.Depth==15) {
352 rgb_flag = GL_TRUE;
353 redscale = greenscale = bluescale = alphascale = 31.0;
354 redbits = greenbits = bluebits = 5;
355 alphabits = 0;
356 index_bits = 0;
357 }
358 else if (SVGABuffer.Depth==16) {
359 rgb_flag = GL_TRUE;
360 redscale = bluescale = alphascale = 31.0;
361 greenscale = 63.0;
362 redbits = bluebits = 5;
363 greenbits = 6;
364 alphabits = 0;
365 index_bits = 0;
366 }
367
368 ctx = (SVGAMesaContext) calloc( 1, sizeof(struct svgamesa_context) );
369 if (!ctx) {
370 return NULL;
371 }
372
373 ctx->gl_vis = gl_create_visual( rgb_flag,
374 alpha_flag,
375 doubleBuffer,
376 GL_FALSE, /* stereo */
377 16, /* depth_size */
378 8, /* stencil_size */
379 16, /* accum_size */
380 index_bits,
381 redbits, greenbits,
382 bluebits, alphabits );
383
384 ctx->gl_ctx = gl_create_context( ctx->gl_vis,
385 NULL, /* share list context */
386 (void *) ctx, GL_TRUE );
387
388 ctx->gl_buffer = gl_create_framebuffer( ctx->gl_vis );
389
390 ctx->index = 1;
391 ctx->red = ctx->green = ctx->blue = 255;
392
393 ctx->width = ctx->height = 0; /* temporary until first "make-current" */
394 #endif
395 return ctx;
396 }
397
398 /*
399 * Destroy the given VGA/Mesa context.
400 */
401 void SVGAMesaDestroyContext( SVGAMesaContext ctx )
402 {
403 #ifndef DEV
404 if (ctx) {
405 gl_destroy_visual( ctx->gl_vis );
406 gl_destroy_context( ctx->gl_ctx );
407 gl_destroy_framebuffer( ctx->gl_buffer );
408 free( ctx );
409 if (ctx==SVGAMesa) {
410 SVGAMesa = NULL;
411 }
412 }
413 #endif
414 }
415
416 /*
417 * Make the specified VGA/Mesa context the current one.
418 */
419 void SVGAMesaMakeCurrent( SVGAMesaContext ctx )
420 {
421 #ifndef DEV
422 SVGAMesa = ctx;
423 svgamesa_update_state( ctx->gl_ctx );
424 gl_make_current( ctx->gl_ctx, ctx->gl_buffer );
425
426 if (ctx->width==0 || ctx->height==0) {
427 /* setup initial viewport */
428 ctx->width = vga_getxdim();
429 ctx->height = vga_getydim();
430 gl_Viewport( ctx->gl_ctx, 0, 0, ctx->width, ctx->height );
431 }
432 #endif
433 }
434
435 /*
436 * Return a handle to the current VGA/Mesa context.
437 */
438 SVGAMesaContext SVGAMesaGetCurrentContext( void )
439 {
440 return SVGAMesa;
441 }
442
443 /*
444 * Swap front/back buffers for current context if double buffered.
445 */
446 void SVGAMesaSwapBuffers( void )
447 {
448 void * tmpptr;
449
450 /* vga_waitretrace(); */
451 copy_buffer(SVGABuffer.BackBuffer);
452
453 #ifndef DEV
454 FLUSH_VB( SVGAMesa->gl_ctx, "swap buffers" );
455 if (SVGAMesa->gl_vis->DBflag)
456 #endif /* DEV */
457 {
458 #ifdef SVGA_DEBUG
459 sprintf(cbuf,"SVGAMesaSwapBuffers : Swapping...");
460 SVGAlog(cbuf);
461 #endif /* SVGA_DEBUG */
462 tmpptr=SVGABuffer.BackBuffer;
463 SVGABuffer.BackBuffer=SVGABuffer.FrontBuffer;
464 SVGABuffer.FrontBuffer=tmpptr;
465 #ifdef SVGA_DEBUG
466 sprintf(cbuf,"SVGAMesaSwapBuffers : WriteBuffer : %p\n"
467 " Readbuffer : %p", \
468 SVGABuffer.BackBuffer, SVGABuffer.FrontBuffer );
469 SVGAlog(cbuf);
470 #endif /* SVGA_DEBUG */
471 }
472 }
473
474 #else /*SVGA*/
475
476 /*
477 * Need this to provide at least one external definition when SVGA is
478 * not defined on the compiler command line.
479 */
480
481 int gl_svga_dummy_function(void)
482 {
483 return 0;
484 }
485
486 #endif /*SVGA*/
487