compilation fixes
[mesa.git] / src / mesa / drivers / svga / svgamesa.c
1 /* $Id: svgamesa.c,v 1.23 2002/11/11 18:42:38 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 5.0
6 * Copyright (C) 1995-2002 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 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <vga.h>
41 #include "GL/svgamesa.h"
42 #include "context.h"
43 #include "extensions.h"
44 #include "imports.h"
45 #include "matrix.h"
46 #include "mtypes.h"
47 #include "swrast/swrast.h"
48 #include "svgapix.h"
49 #include "svgamesa8.h"
50 #include "svgamesa15.h"
51 #include "svgamesa16.h"
52 #include "svgamesa24.h"
53 #include "svgamesa32.h"
54
55 struct svga_buffer SVGABuffer;
56 vga_modeinfo * SVGAInfo;
57 SVGAMesaContext SVGAMesa; /* the current context */
58
59 #ifdef SVGA_DEBUG
60
61 #include <sys/types.h>
62 #include <signal.h>
63
64 FILE * logfile;
65 char cbuf[1024]={0};
66
67 void SVGAlog(char * what)
68 {
69 logfile=fopen("svgamesa.log","a");
70 if (!logfile) return;
71 fprintf(logfile,"%s\n",what);
72 fclose(logfile);
73 }
74 #endif
75
76 /**********************************************************************/
77 /***** Init stuff... *****/
78 /**********************************************************************/
79
80 int SVGAMesaInit( int GraphMode )
81 {
82 vga_init();
83 if (!vga_hasmode(GraphMode))
84 {
85 fprintf(stderr,"GraphMode %d unavailable...",GraphMode);
86 #ifdef SVGA_DEBUG
87 SVGAlog("SVGAMesaInit: invalid GraphMode (doesn't exist)");
88 #endif
89 return(1);
90 }
91 SVGAInfo=vga_getmodeinfo(GraphMode);
92 if (SVGAInfo->flags & IS_MODEX)
93 {
94 fprintf(stderr,"ModeX not implemented...");
95 #ifdef SVGA_DEBUG
96 SVGAlog("SVGAMesaInit: invalid GraphMode (ModeX)");
97 #endif
98 return(2);
99 }
100 if (!SVGAInfo->bytesperpixel)
101 {
102 fprintf(stderr,"1 / 4 bit color not implemented...");
103 #ifdef SVGA_DEBUG
104 SVGAlog("SVGAMesaInit: invalid GraphMode (1 or 4 bit)");
105 #endif
106 return(3);
107 }
108 switch (SVGAInfo->colors) {
109 case 256: SVGABuffer.Depth = 8; break;
110 case 32768: SVGABuffer.Depth = 15; break;
111 case 65536: SVGABuffer.Depth = 16; break;
112 default: SVGABuffer.Depth = SVGAInfo->bytesperpixel<<3; break;
113 }
114 SVGABuffer.BufferSize=SVGAInfo->linewidth*SVGAInfo->height;
115 #ifdef SVGA_DEBUG
116 sprintf(cbuf,"SVGAMesaInit: double buffer info.\n" \
117 " depth : %d\n" \
118 " mode : %d\n" \
119 " width : %d\n" \
120 " height : %d\n" \
121 " bufsize: %d\n", \
122 SVGABuffer.Depth,GraphMode,SVGAInfo->linewidth, \
123 SVGAInfo->height,SVGABuffer.BufferSize);
124 SVGAlog(cbuf);
125 #endif
126 SVGABuffer.FrontBuffer=(void*)malloc(SVGABuffer.BufferSize + 4);
127 if (!SVGABuffer.FrontBuffer) {
128 {
129 fprintf(stderr,"Not enough RAM for FRONT_LEFT_BUFFER...");
130 #ifdef SVGA_DEBUG
131 SVGAlog("SVGAMesaInit: Not enough RAM (front buffer)");
132 #endif
133 return(4);
134 }
135 }
136 #ifdef SVGA_DEBUG
137 sprintf(cbuf,"SVGAMesaInit: FrontBuffer - %p",SVGABuffer.FrontBuffer);
138 SVGAlog(cbuf);
139 #endif
140 SVGABuffer.BackBuffer=(void*)malloc(SVGABuffer.BufferSize + 4);
141 if (!SVGABuffer.BackBuffer) {
142 {
143 free(SVGABuffer.FrontBuffer);
144 fprintf(stderr,"Not enough RAM for BACK_LEFT_BUFFER...");
145 #ifdef SVGA_DEBUG
146 SVGAlog("SVGAMesaInit: Not enough RAM (back buffer)");
147 #endif
148 return(5);
149 }
150 }
151 #ifdef SVGA_DEBUG
152 sprintf(cbuf,"SVGAMesaInit: BackBuffer - %p",SVGABuffer.BackBuffer);
153 SVGAlog(cbuf);
154 #endif
155
156 vga_setmode(GraphMode);
157 SVGABuffer.VideoRam=vga_getgraphmem();
158 #ifdef SVGA_DEBUG
159 sprintf(cbuf,"SVGAMesaInit: VRAM - %p",SVGABuffer.VideoRam);
160 SVGAlog(cbuf);
161 sprintf(cbuf,"SVGAMesaInit: done. (Mode %d)",GraphMode);
162 SVGAlog(cbuf);
163 #endif
164
165 SVGABuffer.DrawBuffer = SVGABuffer.BackBuffer;
166 SVGABuffer.ReadBuffer = SVGABuffer.BackBuffer;
167
168 return 0;
169 }
170
171 int SVGAMesaClose( void )
172 {
173 vga_setmode(TEXT);
174 free(SVGABuffer.FrontBuffer);
175 free(SVGABuffer.BackBuffer);
176 return 0;
177 }
178
179 void SVGAMesaSetCI(int ndx, GLubyte red, GLubyte green, GLubyte blue)
180 {
181 if (ndx<256)
182 vga_setpalette(ndx, red>>2, green>>2, blue>>2);
183 }
184
185 /**********************************************************************/
186 /***** Miscellaneous functions *****/
187 /**********************************************************************/
188
189 static void copy_buffer( const GLubyte * buffer) {
190 int size = SVGABuffer.BufferSize, page = 0;
191
192 #ifdef SVGA_DEBUG
193 sprintf(cbuf,"copy_buffer: copy %p to %p",buffer,SVGABuffer.VideoRam);
194 SVGAlog(cbuf);
195 #endif
196
197 while(size>0) {
198 vga_setpage(page++);
199 if (size>>16) {
200 memcpy(SVGABuffer.VideoRam,buffer,0x10000);
201 buffer+=0x10000;
202 }else{
203 memcpy(SVGABuffer.VideoRam,buffer,size & 0xffff);
204 }
205 size-=0xffff;
206 }
207 }
208
209 static void get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height )
210 {
211 *width = SVGAMesa->width = vga_getxdim();
212 *height = SVGAMesa->height = vga_getydim();
213 }
214
215
216 static void set_buffer( GLcontext *ctx, GLframebuffer *colorBuffer,
217 GLenum buffer )
218 {
219 /* We can ignore colorBuffer since we don't support a MakeCurrentRead()
220 * function.
221 */
222 (void) colorBuffer;
223
224 if (buffer == GL_FRONT_LEFT) {
225 SVGABuffer.ReadBuffer = SVGABuffer.FrontBuffer;
226 SVGABuffer.DrawBuffer = SVGABuffer.FrontBuffer;
227 #if 0
228 void * tmpptr;
229 /* vga_waitretrace(); */
230 copy_buffer(SVGABuffer.FrontBuffer);
231 tmpptr=SVGABuffer.BackBuffer;
232 SVGABuffer.BackBuffer=SVGABuffer.FrontBuffer;
233 SVGABuffer.FrontBuffer=tmpptr;
234 #endif
235 }
236 else if (buffer == GL_BACK_LEFT) {
237 SVGABuffer.ReadBuffer = SVGABuffer.BackBuffer;
238 SVGABuffer.DrawBuffer = SVGABuffer.BackBuffer;
239 #if 0
240 /* vga_waitretrace(); */
241 copy_buffer(SVGABuffer.BackBuffer);
242 #endif
243 }
244 }
245
246 /**********************************************************************/
247 /***** *****/
248 /**********************************************************************/
249
250 static void svgamesa_update_state( GLcontext *ctx, GLuint new_state )
251 {
252 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx );
253
254 /* Initialize all the pointers in the DD struct. Do this whenever */
255 /* a new context is made current or we change buffers via set_buffer! */
256
257 ctx->Driver.UpdateState = svgamesa_update_state;
258
259 ctx->Driver.GetBufferSize = get_buffer_size;
260 ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
261
262 /* Software rasterizer pixel paths:
263 */
264 ctx->Driver.Accum = _swrast_Accum;
265 ctx->Driver.Bitmap = _swrast_Bitmap;
266 ctx->Driver.CopyPixels = _swrast_CopyPixels;
267 ctx->Driver.DrawPixels = _swrast_DrawPixels;
268 ctx->Driver.ReadPixels = _swrast_ReadPixels;
269 ctx->Driver.DrawBuffer = _swrast_DrawBuffer;
270
271 /* Fill in the swrast driver interface:
272 */
273 swdd->SetBuffer = set_buffer;
274
275 switch (SVGABuffer.Depth) {
276 case 8: ctx->Driver.ClearIndex = __clear_index8;
277 ctx->Driver.Clear = __clear8;
278
279 swdd->ReadCI32Span = __read_ci32_span8;
280 swdd->ReadCI32Pixels = __read_ci32_pixels8;
281 swdd->WriteCI8Span = __write_ci8_span8;
282 swdd->WriteCI32Span = __write_ci32_span8;
283 swdd->WriteCI32Pixels = __write_ci32_pixels8;
284 swdd->WriteMonoCISpan = __write_mono_ci_span8;
285 swdd->WriteMonoCIPixels = __write_mono_ci_pixels8;
286 #ifdef SVGA_DEBUG
287 SVGAlog("SVGAUpdateState: 8 bit mode.");
288 #endif
289
290 break;
291 case 15: ctx->Driver.ClearColor = __clear_color15;
292 ctx->Driver.Clear = __clear15;
293
294 swdd->ReadRGBASpan = __read_rgba_span15;
295 swdd->ReadRGBAPixels = __read_rgba_pixels15;
296 swdd->WriteRGBASpan = __write_rgba_span15;
297 swdd->WriteRGBAPixels = __write_rgba_pixels15;
298 swdd->WriteMonoRGBASpan = __write_mono_rgba_span15;
299 swdd->WriteMonoRGBAPixels = __write_mono_rgba_pixels15;
300 #ifdef SVGA_DEBUG
301 SVGAlog("SVGAUpdateState: 15 bit mode.");
302 #endif
303 break;
304 case 16: ctx->Driver.ClearColor = __clear_color16;
305 ctx->Driver.Clear = __clear16;
306
307 swdd->ReadRGBASpan = __read_rgba_span16;
308 swdd->ReadRGBAPixels = __read_rgba_pixels16;
309 swdd->WriteRGBASpan = __write_rgba_span16;
310 swdd->WriteRGBAPixels = __write_rgba_pixels16;
311 swdd->WriteMonoRGBASpan = __write_mono_rgba_span16;
312 swdd->WriteMonoRGBAPixels = __write_mono_rgba_pixels16;
313 break;
314 #ifdef SVGA_DEBUG
315 SVGAlog("SVGAUpdateState: 16 bit mode.");
316 #endif
317 case 24: ctx->Driver.ClearColor = __clear_color24;
318 ctx->Driver.Clear = __clear24;
319
320 swdd->ReadRGBASpan = __read_rgba_span24;
321 swdd->ReadRGBAPixels = __read_rgba_pixels24;
322 swdd->WriteRGBASpan = __write_rgba_span24;
323 swdd->WriteRGBAPixels = __write_rgba_pixels24;
324 swdd->WriteMonoRGBASpan = __write_mono_rgba_span24;
325 swdd->WriteMonoRGBAPixels = __write_mono_rgba_pixels24;
326 break;
327 #ifdef SVGA_DEBUG
328 SVGAlog("SVGAUpdateState: 32 bit mode.");
329 #endif
330 case 32: ctx->Driver.ClearColor = __clear_color32;
331 ctx->Driver.Clear = __clear32;
332
333 swdd->ReadRGBASpan = __read_rgba_span32;
334 swdd->ReadRGBAPixels = __read_rgba_pixels32;
335 swdd->WriteRGBASpan = __write_rgba_span32;
336 swdd->WriteRGBAPixels = __write_rgba_pixels32;
337 swdd->WriteMonoRGBASpan = __write_mono_rgba_span32;
338 swdd->WriteMonoRGBAPixels = __write_mono_rgba_pixels32;
339 }
340 }
341
342 /*
343 * Create a new VGA/Mesa context and return a handle to it.
344 */
345 SVGAMesaContext SVGAMesaCreateContext( GLboolean doubleBuffer )
346 {
347 SVGAMesaContext ctx;
348 #ifndef DEV
349 GLboolean rgb_flag;
350 GLfloat redscale, greenscale, bluescale, alphascale;
351 GLint index_bits;
352 GLint redbits, greenbits, bluebits, alphabits;
353
354 /* determine if we're in RGB or color index mode */
355 if ((SVGABuffer.Depth==32) || (SVGABuffer.Depth==24)) {
356 rgb_flag = GL_TRUE;
357 redscale = greenscale = bluescale = alphascale = 255.0;
358 redbits = greenbits = bluebits = 8;
359 alphabits = 0;
360 index_bits = 0;
361 }
362 else if (SVGABuffer.Depth==8) {
363 rgb_flag = GL_FALSE;
364 redscale = greenscale = bluescale = alphascale = 0.0;
365 redbits = greenbits = bluebits = alphabits = 0;
366 index_bits = 8;
367 }
368 else if (SVGABuffer.Depth==15) {
369 rgb_flag = GL_TRUE;
370 redscale = greenscale = bluescale = alphascale = 31.0;
371 redbits = greenbits = bluebits = 5;
372 alphabits = 0;
373 index_bits = 0;
374 }
375 else if (SVGABuffer.Depth==16) {
376 rgb_flag = GL_TRUE;
377 redscale = bluescale = alphascale = 31.0;
378 greenscale = 63.0;
379 redbits = bluebits = 5;
380 greenbits = 6;
381 alphabits = 0;
382 index_bits = 0;
383 }
384
385 ctx = (SVGAMesaContext) calloc( 1, sizeof(struct svgamesa_context) );
386 if (!ctx) {
387 return NULL;
388 }
389
390 ctx->gl_vis = _mesa_create_visual( rgb_flag,
391 doubleBuffer,
392 GL_FALSE, /* stereo */
393 redbits, greenbits,
394 bluebits, alphabits,
395 index_bits,
396 16, /* depth_size */
397 8, /* stencil_size */
398 16, 16, 16, 16, /* accum_size */
399 1 /* samples */
400 );
401
402 ctx->gl_ctx = _mesa_create_context( ctx->gl_vis,
403 NULL, /* share list context */
404 (void *) ctx, GL_FALSE );
405
406 _mesa_enable_sw_extensions(ctx->gl_ctx);
407 _mesa_enable_1_3_extensions(ctx->gl_ctx);
408
409 ctx->gl_buffer = _mesa_create_framebuffer( ctx->gl_vis,
410 ctx->gl_vis->depthBits > 0,
411 ctx->gl_vis->stencilBits > 0,
412 ctx->gl_vis->accumRedBits > 0,
413 ctx->gl_vis->alphaBits > 0 );
414
415 ctx->width = ctx->height = 0; /* temporary until first "make-current" */
416 #endif
417 return ctx;
418 }
419
420 /*
421 * Destroy the given VGA/Mesa context.
422 */
423 void SVGAMesaDestroyContext( SVGAMesaContext ctx )
424 {
425 #ifndef DEV
426 if (ctx) {
427 _mesa_destroy_visual( ctx->gl_vis );
428 _mesa_destroy_context( ctx->gl_ctx );
429 _mesa_destroy_framebuffer( ctx->gl_buffer );
430 free( ctx );
431 if (ctx==SVGAMesa) {
432 SVGAMesa = NULL;
433 }
434 }
435 #endif
436 }
437
438 /*
439 * Make the specified VGA/Mesa context the current one.
440 */
441 void SVGAMesaMakeCurrent( SVGAMesaContext ctx )
442 {
443 #ifndef DEV
444 SVGAMesa = ctx;
445 svgamesa_update_state( ctx->gl_ctx, ~0 );
446 _mesa_make_current( ctx->gl_ctx, ctx->gl_buffer );
447
448 if (ctx->width==0 || ctx->height==0) {
449 /* setup initial viewport */
450 ctx->width = vga_getxdim();
451 ctx->height = vga_getydim();
452 _mesa_set_viewport( ctx->gl_ctx, 0, 0, ctx->width, ctx->height );
453 }
454 #endif
455 }
456
457 /*
458 * Return a handle to the current VGA/Mesa context.
459 */
460 SVGAMesaContext SVGAMesaGetCurrentContext( void )
461 {
462 return SVGAMesa;
463 }
464
465 /*
466 * Swap front/back buffers for current context if double buffered.
467 */
468 void SVGAMesaSwapBuffers( void )
469 {
470 #if 000
471 void * tmpptr;
472 #endif
473
474 /* vga_waitretrace(); */
475 copy_buffer(SVGABuffer.BackBuffer);
476
477 #ifndef DEV
478 _mesa_notifySwapBuffers( SVGAMesa->gl_ctx );
479 if (SVGAMesa->gl_vis->doubleBufferMode)
480 #endif /* DEV */
481 {
482 #ifdef SVGA_DEBUG
483 sprintf(cbuf,"SVGAMesaSwapBuffers : Swapping...");
484 SVGAlog(cbuf);
485 #endif /* SVGA_DEBUG */
486 #if 000
487 tmpptr=SVGABuffer.BackBuffer;
488 SVGABuffer.BackBuffer=SVGABuffer.FrontBuffer;
489 SVGABuffer.FrontBuffer=tmpptr;
490 #endif
491 #ifdef SVGA_DEBUG
492 sprintf(cbuf,"SVGAMesaSwapBuffers : WriteBuffer : %p\n"
493 " Readbuffer : %p", \
494 SVGABuffer.BackBuffer, SVGABuffer.FrontBuffer );
495 SVGAlog(cbuf);
496 #endif /* SVGA_DEBUG */
497 }
498 }
499
500 #else /*SVGA*/
501
502 /*
503 * Need this to provide at least one external definition when SVGA is
504 * not defined on the compiler command line.
505 */
506
507 int gl_svga_dummy_function(void)
508 {
509 return 0;
510 }
511
512 #endif /*SVGA*/
513