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