Merge branch 'mesa_7_6_branch' into mesa_7_7_branch
[mesa.git] / src / mesa / drivers / svga / svgamesa.c
1
2 /*
3 * Mesa 3-D graphics library
4 * Version: 5.0
5 * Copyright (C) 1995-2002 Brian Paul
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22
23 /*
24 * SVGA driver for Mesa.
25 * Original author: Brian Paul
26 * Additional authors: Slawomir Szczyrba <steev@hot.pl> (Mesa 3.2)
27 */
28
29
30 #ifdef HAVE_CONFIG_H
31 #include "conf.h"
32 #endif
33
34 #ifdef SVGA
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <vga.h>
40 #include "GL/svgamesa.h"
41 #include "main/buffers.h"
42 #include "main/context.h"
43 #include "main/extensions.h"
44 #include "main/imports.h"
45 #include "main/matrix.h"
46 #include "main/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 * We only implement this function as a mechanism to check if the
217 * framebuffer size has changed (and update corresponding state).
218 */
219 static void viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
220 {
221 GLuint newWidth, newHeight;
222 GLframebuffer *buffer = ctx->WinSysDrawBuffer;
223 get_buffer_size( buffer, &newWidth, &newHeight );
224 if (buffer->Width != newWidth || buffer->Height != newHeight) {
225 _mesa_resize_framebuffer(ctx, buffer, newWidth, newHeight );
226 }
227 }
228
229 static void set_buffer( GLcontext *ctx, GLframebuffer *colorBuffer,
230 GLenum buffer )
231 {
232 /* We can ignore colorBuffer since we don't support a MakeCurrentRead()
233 * function.
234 */
235 (void) colorBuffer;
236
237 if (buffer == GL_FRONT_LEFT) {
238 SVGABuffer.ReadBuffer = SVGABuffer.FrontBuffer;
239 SVGABuffer.DrawBuffer = SVGABuffer.FrontBuffer;
240 #if 0
241 void * tmpptr;
242 /* vga_waitretrace(); */
243 copy_buffer(SVGABuffer.FrontBuffer);
244 tmpptr=SVGABuffer.BackBuffer;
245 SVGABuffer.BackBuffer=SVGABuffer.FrontBuffer;
246 SVGABuffer.FrontBuffer=tmpptr;
247 #endif
248 }
249 else if (buffer == GL_BACK_LEFT) {
250 SVGABuffer.ReadBuffer = SVGABuffer.BackBuffer;
251 SVGABuffer.DrawBuffer = SVGABuffer.BackBuffer;
252 #if 0
253 /* vga_waitretrace(); */
254 copy_buffer(SVGABuffer.BackBuffer);
255 #endif
256 }
257 }
258
259 /**********************************************************************/
260 /***** *****/
261 /**********************************************************************/
262
263 static void svgamesa_update_state( GLcontext *ctx, GLuint new_state )
264 {
265 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx );
266
267 /* Initialize all the pointers in the DD struct. Do this whenever */
268 /* a new context is made current or we change buffers via set_buffer! */
269
270 ctx->Driver.UpdateState = svgamesa_update_state;
271
272 ctx->Driver.GetBufferSize = get_buffer_size;
273 ctx->Driver.Viewport = viewport;
274
275 /* Fill in the swrast driver interface:
276 */
277 swdd->SetBuffer = set_buffer;
278
279 switch (SVGABuffer.Depth) {
280 case 8: ctx->Driver.ClearIndex = __clear_index8;
281 ctx->Driver.Clear = __clear8;
282
283 swdd->ReadCI32Span = __read_ci32_span8;
284 swdd->ReadCI32Pixels = __read_ci32_pixels8;
285 swdd->WriteCI8Span = __write_ci8_span8;
286 swdd->WriteCI32Span = __write_ci32_span8;
287 swdd->WriteCI32Pixels = __write_ci32_pixels8;
288 swdd->WriteMonoCISpan = __write_mono_ci_span8;
289 swdd->WriteMonoCIPixels = __write_mono_ci_pixels8;
290 #ifdef SVGA_DEBUG
291 SVGAlog("SVGAUpdateState: 8 bit mode.");
292 #endif
293
294 break;
295 case 15: ctx->Driver.ClearColor = __clear_color15;
296 ctx->Driver.Clear = __clear15;
297
298 swdd->ReadRGBASpan = __read_rgba_span15;
299 swdd->ReadRGBAPixels = __read_rgba_pixels15;
300 swdd->WriteRGBASpan = __write_rgba_span15;
301 swdd->WriteRGBAPixels = __write_rgba_pixels15;
302 swdd->WriteMonoRGBASpan = __write_mono_rgba_span15;
303 swdd->WriteMonoRGBAPixels = __write_mono_rgba_pixels15;
304 #ifdef SVGA_DEBUG
305 SVGAlog("SVGAUpdateState: 15 bit mode.");
306 #endif
307 break;
308 case 16: ctx->Driver.ClearColor = __clear_color16;
309 ctx->Driver.Clear = __clear16;
310
311 swdd->ReadRGBASpan = __read_rgba_span16;
312 swdd->ReadRGBAPixels = __read_rgba_pixels16;
313 swdd->WriteRGBASpan = __write_rgba_span16;
314 swdd->WriteRGBAPixels = __write_rgba_pixels16;
315 swdd->WriteMonoRGBASpan = __write_mono_rgba_span16;
316 swdd->WriteMonoRGBAPixels = __write_mono_rgba_pixels16;
317 break;
318 #ifdef SVGA_DEBUG
319 SVGAlog("SVGAUpdateState: 16 bit mode.");
320 #endif
321 case 24: ctx->Driver.ClearColor = __clear_color24;
322 ctx->Driver.Clear = __clear24;
323
324 swdd->ReadRGBASpan = __read_rgba_span24;
325 swdd->ReadRGBAPixels = __read_rgba_pixels24;
326 swdd->WriteRGBASpan = __write_rgba_span24;
327 swdd->WriteRGBAPixels = __write_rgba_pixels24;
328 swdd->WriteMonoRGBASpan = __write_mono_rgba_span24;
329 swdd->WriteMonoRGBAPixels = __write_mono_rgba_pixels24;
330 break;
331 #ifdef SVGA_DEBUG
332 SVGAlog("SVGAUpdateState: 32 bit mode.");
333 #endif
334 case 32: ctx->Driver.ClearColor = __clear_color32;
335 ctx->Driver.Clear = __clear32;
336
337 swdd->ReadRGBASpan = __read_rgba_span32;
338 swdd->ReadRGBAPixels = __read_rgba_pixels32;
339 swdd->WriteRGBASpan = __write_rgba_span32;
340 swdd->WriteRGBAPixels = __write_rgba_pixels32;
341 swdd->WriteMonoRGBASpan = __write_mono_rgba_span32;
342 swdd->WriteMonoRGBAPixels = __write_mono_rgba_pixels32;
343 }
344 }
345
346 /*
347 * Create a new VGA/Mesa context and return a handle to it.
348 */
349 SVGAMesaContext SVGAMesaCreateContext( GLboolean doubleBuffer )
350 {
351 SVGAMesaContext ctx;
352 #ifndef DEV
353 GLboolean rgb_flag;
354 GLfloat redscale, greenscale, bluescale, alphascale;
355 GLint index_bits;
356 GLint redbits, greenbits, bluebits, alphabits;
357
358 /* determine if we're in RGB or color index mode */
359 if ((SVGABuffer.Depth==32) || (SVGABuffer.Depth==24)) {
360 rgb_flag = GL_TRUE;
361 redscale = greenscale = bluescale = alphascale = 255.0;
362 redbits = greenbits = bluebits = 8;
363 alphabits = 0;
364 index_bits = 0;
365 }
366 else if (SVGABuffer.Depth==8) {
367 rgb_flag = GL_FALSE;
368 redscale = greenscale = bluescale = alphascale = 0.0;
369 redbits = greenbits = bluebits = alphabits = 0;
370 index_bits = 8;
371 }
372 else if (SVGABuffer.Depth==15) {
373 rgb_flag = GL_TRUE;
374 redscale = greenscale = bluescale = alphascale = 31.0;
375 redbits = greenbits = bluebits = 5;
376 alphabits = 0;
377 index_bits = 0;
378 }
379 else if (SVGABuffer.Depth==16) {
380 rgb_flag = GL_TRUE;
381 redscale = bluescale = alphascale = 31.0;
382 greenscale = 63.0;
383 redbits = bluebits = 5;
384 greenbits = 6;
385 alphabits = 0;
386 index_bits = 0;
387 }
388
389 ctx = (SVGAMesaContext) calloc( 1, sizeof(struct svgamesa_context) );
390 if (!ctx) {
391 return NULL;
392 }
393
394 ctx->gl_vis = _mesa_create_visual( rgb_flag,
395 doubleBuffer,
396 GL_FALSE, /* stereo */
397 redbits, greenbits,
398 bluebits, alphabits,
399 index_bits,
400 16, /* depth_size */
401 8, /* stencil_size */
402 16, 16, 16, 16, /* accum_size */
403 1 /* samples */
404 );
405
406 ctx->gl_ctx = _mesa_create_context( ctx->gl_vis,
407 NULL, /* share list context */
408 (void *) ctx, GL_FALSE );
409
410 _mesa_enable_sw_extensions(ctx->gl_ctx);
411 _mesa_enable_1_3_extensions(ctx->gl_ctx);
412
413 _mesa_init_driver_functions(&ctx->Driver);
414
415 ctx->gl_buffer = _mesa_create_framebuffer( ctx->gl_vis,
416 ctx->gl_vis->depthBits > 0,
417 ctx->gl_vis->stencilBits > 0,
418 ctx->gl_vis->accumRedBits > 0,
419 ctx->gl_vis->alphaBits > 0 );
420
421 ctx->width = ctx->height = 0; /* temporary until first "make-current" */
422 #endif
423 return ctx;
424 }
425
426 /*
427 * Destroy the given VGA/Mesa context.
428 */
429 void SVGAMesaDestroyContext( SVGAMesaContext ctx )
430 {
431 #ifndef DEV
432 if (ctx) {
433 _mesa_destroy_visual( ctx->gl_vis );
434 _mesa_destroy_context( ctx->gl_ctx );
435 free( ctx );
436 if (ctx==SVGAMesa) {
437 SVGAMesa = NULL;
438 }
439 }
440 #endif
441 }
442
443 /*
444 * Make the specified VGA/Mesa context the current one.
445 */
446 void SVGAMesaMakeCurrent( SVGAMesaContext ctx )
447 {
448 #ifndef DEV
449 SVGAMesa = ctx;
450 svgamesa_update_state( ctx->gl_ctx, ~0 );
451 _mesa_make_current( ctx->gl_ctx, ctx->gl_buffer );
452
453 if (ctx->width==0 || ctx->height==0) {
454 ctx->width = vga_getxdim();
455 ctx->height = vga_getydim();
456 }
457 #endif
458 }
459
460 /*
461 * Return a handle to the current VGA/Mesa context.
462 */
463 SVGAMesaContext SVGAMesaGetCurrentContext( void )
464 {
465 return SVGAMesa;
466 }
467
468 /*
469 * Swap front/back buffers for current context if double buffered.
470 */
471 void SVGAMesaSwapBuffers( void )
472 {
473 #if 000
474 void * tmpptr;
475 #endif
476
477 /* vga_waitretrace(); */
478 copy_buffer(SVGABuffer.BackBuffer);
479
480 #ifndef DEV
481 _mesa_notifySwapBuffers( SVGAMesa->gl_ctx );
482 if (SVGAMesa->gl_vis->doubleBufferMode)
483 #endif /* DEV */
484 {
485 #ifdef SVGA_DEBUG
486 sprintf(cbuf,"SVGAMesaSwapBuffers : Swapping...");
487 SVGAlog(cbuf);
488 #endif /* SVGA_DEBUG */
489 #if 000
490 tmpptr=SVGABuffer.BackBuffer;
491 SVGABuffer.BackBuffer=SVGABuffer.FrontBuffer;
492 SVGABuffer.FrontBuffer=tmpptr;
493 #endif
494 #ifdef SVGA_DEBUG
495 sprintf(cbuf,"SVGAMesaSwapBuffers : WriteBuffer : %p\n"
496 " Readbuffer : %p", \
497 SVGABuffer.BackBuffer, SVGABuffer.FrontBuffer );
498 SVGAlog(cbuf);
499 #endif /* SVGA_DEBUG */
500 }
501 }
502
503 #else /*SVGA*/
504
505 /*
506 * Need this to provide at least one external definition when SVGA is
507 * not defined on the compiler command line.
508 */
509 extern int gl_svga_dummy_function(void);
510 int gl_svga_dummy_function(void)
511 {
512 return 0;
513 }
514
515 #endif /*SVGA*/
516