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