1 /* $Id: svgamesa.c,v 1.19 2002/06/15 02:38:17 brianp Exp $ */
4 * Mesa 3-D graphics library
6 * Copyright (C) 1995-2000 Brian Paul
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.
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.
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.
25 * SVGA driver for Mesa.
26 * Original author: Brian Paul
27 * Additional authors: Slawomir Szczyrba <steev@hot.pl> (Mesa 3.2)
44 #include "GL/svgamesa.h"
46 #include "extensions.h"
50 #include "swrast/swrast.h"
54 #include "svgamesa8.h"
55 #include "svgamesa15.h"
56 #include "svgamesa16.h"
57 #include "svgamesa24.h"
58 #include "svgamesa32.h"
60 struct svga_buffer SVGABuffer
;
61 vga_modeinfo
* SVGAInfo
;
62 SVGAMesaContext SVGAMesa
; /* the current context */
66 #include <sys/types.h>
72 void SVGAlog(char * what
)
74 logfile
=fopen("svgamesa.log","a");
76 fprintf(logfile
,"%s\n",what
);
81 /**********************************************************************/
82 /***** Init stuff... *****/
83 /**********************************************************************/
85 int SVGAMesaInit( int GraphMode
)
88 if (!vga_hasmode(GraphMode
))
90 fprintf(stderr
,"GraphMode %d unavailable...",GraphMode
);
92 SVGAlog("SVGAMesaInit: invalid GraphMode (doesn't exist)");
96 SVGAInfo
=vga_getmodeinfo(GraphMode
);
97 if (SVGAInfo
->flags
& IS_MODEX
)
99 fprintf(stderr
,"ModeX not implemented...");
101 SVGAlog("SVGAMesaInit: invalid GraphMode (ModeX)");
105 if (!SVGAInfo
->bytesperpixel
)
107 fprintf(stderr
,"1 / 4 bit color not implemented...");
109 SVGAlog("SVGAMesaInit: invalid GraphMode (1 or 4 bit)");
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;
119 SVGABuffer
.BufferSize
=SVGAInfo
->linewidth
*SVGAInfo
->height
;
121 sprintf(cbuf
,"SVGAMesaInit: double buffer info.\n" \
127 SVGABuffer
.Depth
,GraphMode
,SVGAInfo
->linewidth
, \
128 SVGAInfo
->height
,SVGABuffer
.BufferSize
);
131 SVGABuffer
.FrontBuffer
=(void*)malloc(SVGABuffer
.BufferSize
+ 4);
132 if (!SVGABuffer
.FrontBuffer
) {
134 fprintf(stderr
,"Not enough RAM for FRONT_LEFT_BUFFER...");
136 SVGAlog("SVGAMesaInit: Not enough RAM (front buffer)");
142 sprintf(cbuf
,"SVGAMesaInit: FrontBuffer - %p",SVGABuffer
.FrontBuffer
);
145 SVGABuffer
.BackBuffer
=(void*)malloc(SVGABuffer
.BufferSize
+ 4);
146 if (!SVGABuffer
.BackBuffer
) {
148 free(SVGABuffer
.FrontBuffer
);
149 fprintf(stderr
,"Not enough RAM for BACK_LEFT_BUFFER...");
151 SVGAlog("SVGAMesaInit: Not enough RAM (back buffer)");
157 sprintf(cbuf
,"SVGAMesaInit: BackBuffer - %p",SVGABuffer
.BackBuffer
);
161 vga_setmode(GraphMode
);
162 SVGABuffer
.VideoRam
=vga_getgraphmem();
164 sprintf(cbuf
,"SVGAMesaInit: VRAM - %p",SVGABuffer
.VideoRam
);
166 sprintf(cbuf
,"SVGAMesaInit: done. (Mode %d)",GraphMode
);
170 SVGABuffer
.DrawBuffer
= SVGABuffer
.BackBuffer
;
171 SVGABuffer
.ReadBuffer
= SVGABuffer
.BackBuffer
;
176 int SVGAMesaClose( void )
179 free(SVGABuffer
.FrontBuffer
);
180 free(SVGABuffer
.BackBuffer
);
184 void SVGAMesaSetCI(int ndx
, GLubyte red
, GLubyte green
, GLubyte blue
)
187 vga_setpalette(ndx
, red
>>2, green
>>2, blue
>>2);
190 /**********************************************************************/
191 /***** Miscellaneous functions *****/
192 /**********************************************************************/
194 static void copy_buffer( const GLubyte
* buffer
) {
195 int size
= SVGABuffer
.BufferSize
, page
= 0;
198 sprintf(cbuf
,"copy_buffer: copy %p to %p",buffer
,SVGABuffer
.VideoRam
);
205 memcpy(SVGABuffer
.VideoRam
,buffer
,0x10000);
208 memcpy(SVGABuffer
.VideoRam
,buffer
,size
& 0xffff);
214 static void get_buffer_size( GLframebuffer
*buffer
, GLuint
*width
, GLuint
*height
)
216 *width
= SVGAMesa
->width
= vga_getxdim();
217 *height
= SVGAMesa
->height
= vga_getydim();
220 static void set_draw_buffer( GLcontext
*ctx
, GLenum buffer
)
222 if (buffer
== GL_FRONT_LEFT
) {
223 SVGABuffer
.DrawBuffer
= SVGABuffer
.FrontBuffer
;
225 /* vga_waitretrace(); */
227 copy_buffer(SVGABuffer
.FrontBuffer
);
228 tmpptr
=SVGABuffer
.BackBuffer
;
229 SVGABuffer
.BackBuffer
=SVGABuffer
.FrontBuffer
;
230 SVGABuffer
.FrontBuffer
=tmpptr
;
233 else if (buffer
== GL_BACK_LEFT
) {
234 SVGABuffer
.DrawBuffer
= SVGABuffer
.BackBuffer
;
236 /* vga_waitretrace(); */
237 copy_buffer(SVGABuffer
.BackBuffer
);
241 /* nothing since we don't have any point/line/triangle functions. */
246 static void set_read_buffer( GLcontext
*ctx
, GLframebuffer
*colorBuffer
,
249 /* We can ignore colorBuffer since we don't support a MakeCurrentRead()
254 if (buffer
== GL_FRONT_LEFT
) {
255 SVGABuffer
.ReadBuffer
= SVGABuffer
.FrontBuffer
;
258 /* vga_waitretrace(); */
259 copy_buffer(SVGABuffer
.FrontBuffer
);
260 tmpptr
=SVGABuffer
.BackBuffer
;
261 SVGABuffer
.BackBuffer
=SVGABuffer
.FrontBuffer
;
262 SVGABuffer
.FrontBuffer
=tmpptr
;
265 else if (buffer
== GL_BACK_LEFT
) {
266 SVGABuffer
.ReadBuffer
= SVGABuffer
.BackBuffer
;
268 /* vga_waitretrace(); */
269 copy_buffer(SVGABuffer
.BackBuffer
);
274 /**********************************************************************/
276 /**********************************************************************/
278 static void svgamesa_update_state( GLcontext
*ctx
, GLuint new_state
)
280 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference( ctx
);
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! */
285 ctx
->Driver
.UpdateState
= svgamesa_update_state
;
287 ctx
->Driver
.GetBufferSize
= get_buffer_size
;
288 ctx
->Driver
.SetDrawBuffer
= set_draw_buffer
;
289 ctx
->Driver
.ResizeBuffers
= _swrast_alloc_buffers
;
291 /* Software rasterizer pixel paths:
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
;
299 /* Fill in the swrast driver interface:
301 swdd
->SetReadBuffer
= set_read_buffer
;
303 switch (SVGABuffer
.Depth
) {
304 case 8: ctx
->Driver
.ClearIndex
= __clear_index8
;
305 ctx
->Driver
.Clear
= __clear8
;
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
;
315 SVGAlog("SVGAUpdateState: 8 bit mode.");
319 case 15: ctx
->Driver
.ClearColor
= __clear_color15
;
320 ctx
->Driver
.Clear
= __clear15
;
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
;
329 SVGAlog("SVGAUpdateState: 15 bit mode.");
332 case 16: ctx
->Driver
.ClearColor
= __clear_color16
;
333 ctx
->Driver
.Clear
= __clear16
;
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
;
343 SVGAlog("SVGAUpdateState: 16 bit mode.");
345 case 24: ctx
->Driver
.ClearColor
= __clear_color24
;
346 ctx
->Driver
.Clear
= __clear24
;
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
;
356 SVGAlog("SVGAUpdateState: 32 bit mode.");
358 case 32: ctx
->Driver
.ClearColor
= __clear_color32
;
359 ctx
->Driver
.Clear
= __clear32
;
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
;
371 * Create a new VGA/Mesa context and return a handle to it.
373 SVGAMesaContext
SVGAMesaCreateContext( GLboolean doubleBuffer
)
378 GLfloat redscale
, greenscale
, bluescale
, alphascale
;
380 GLint redbits
, greenbits
, bluebits
, alphabits
;
383 /* determine if we're in RGB or color index mode */
384 if ((SVGABuffer
.Depth
==32) || (SVGABuffer
.Depth
==24)) {
386 redscale
= greenscale
= bluescale
= alphascale
= 255.0;
387 redbits
= greenbits
= bluebits
= 8;
391 else if (SVGABuffer
.Depth
==8) {
393 redscale
= greenscale
= bluescale
= alphascale
= 0.0;
394 redbits
= greenbits
= bluebits
= alphabits
= 0;
397 else if (SVGABuffer
.Depth
==15) {
399 redscale
= greenscale
= bluescale
= alphascale
= 31.0;
400 redbits
= greenbits
= bluebits
= 5;
404 else if (SVGABuffer
.Depth
==16) {
406 redscale
= bluescale
= alphascale
= 31.0;
408 redbits
= bluebits
= 5;
414 ctx
= (SVGAMesaContext
) calloc( 1, sizeof(struct svgamesa_context
) );
419 ctx
->gl_vis
= _mesa_create_visual( rgb_flag
,
421 GL_FALSE
, /* stereo */
426 8, /* stencil_size */
427 16, 16, 16, 16, /* accum_size */
431 _mesa_init_default_imports( &imports
, (void *) ctx
);
432 ctx
->gl_ctx
= _mesa_create_context( ctx
->gl_vis
,
433 NULL
, /* share list context */
436 _mesa_enable_sw_extensions(ctx
->gl_ctx
);
437 _mesa_enable_1_3_extensions(ctx
->gl_ctx
);
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 );
445 ctx
->width
= ctx
->height
= 0; /* temporary until first "make-current" */
451 * Destroy the given VGA/Mesa context.
453 void SVGAMesaDestroyContext( SVGAMesaContext ctx
)
457 _mesa_destroy_visual( ctx
->gl_vis
);
458 _mesa_destroy_context( ctx
->gl_ctx
);
459 _mesa_destroy_framebuffer( ctx
->gl_buffer
);
469 * Make the specified VGA/Mesa context the current one.
471 void SVGAMesaMakeCurrent( SVGAMesaContext ctx
)
475 svgamesa_update_state( ctx
->gl_ctx
, ~0 );
476 _mesa_make_current( ctx
->gl_ctx
, ctx
->gl_buffer
);
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
);
488 * Return a handle to the current VGA/Mesa context.
490 SVGAMesaContext
SVGAMesaGetCurrentContext( void )
496 * Swap front/back buffers for current context if double buffered.
498 void SVGAMesaSwapBuffers( void )
504 /* vga_waitretrace(); */
505 copy_buffer(SVGABuffer
.BackBuffer
);
508 _mesa_swapbuffers( SVGAMesa
->gl_ctx
);
509 if (SVGAMesa
->gl_vis
->doubleBufferMode
)
513 sprintf(cbuf
,"SVGAMesaSwapBuffers : Swapping...");
515 #endif /* SVGA_DEBUG */
517 tmpptr
=SVGABuffer
.BackBuffer
;
518 SVGABuffer
.BackBuffer
=SVGABuffer
.FrontBuffer
;
519 SVGABuffer
.FrontBuffer
=tmpptr
;
522 sprintf(cbuf
,"SVGAMesaSwapBuffers : WriteBuffer : %p\n"
523 " Readbuffer : %p", \
524 SVGABuffer
.BackBuffer
, SVGABuffer
.FrontBuffer
);
526 #endif /* SVGA_DEBUG */
533 * Need this to provide at least one external definition when SVGA is
534 * not defined on the compiler command line.
537 int gl_svga_dummy_function(void)