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