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