3 * Mesa 3-D graphics library
5 * Copyright (C) 1995-2002 Brian Paul
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.
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.
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.
24 * SVGA driver for Mesa.
25 * Original author: Brian Paul
26 * Additional authors: Slawomir Szczyrba <steev@hot.pl> (Mesa 3.2)
40 #include "GL/svgamesa.h"
43 #include "extensions.h"
47 #include "swrast/swrast.h"
49 #include "svgamesa8.h"
50 #include "svgamesa15.h"
51 #include "svgamesa16.h"
52 #include "svgamesa24.h"
53 #include "svgamesa32.h"
55 struct svga_buffer SVGABuffer
;
56 vga_modeinfo
* SVGAInfo
;
57 SVGAMesaContext SVGAMesa
; /* the current context */
61 #include <sys/types.h>
67 void SVGAlog(char * what
)
69 logfile
=fopen("svgamesa.log","a");
71 fprintf(logfile
,"%s\n",what
);
76 /**********************************************************************/
77 /***** Init stuff... *****/
78 /**********************************************************************/
80 int SVGAMesaInit( int GraphMode
)
83 if (!vga_hasmode(GraphMode
))
85 fprintf(stderr
,"GraphMode %d unavailable...",GraphMode
);
87 SVGAlog("SVGAMesaInit: invalid GraphMode (doesn't exist)");
91 SVGAInfo
=vga_getmodeinfo(GraphMode
);
92 if (SVGAInfo
->flags
& IS_MODEX
)
94 fprintf(stderr
,"ModeX not implemented...");
96 SVGAlog("SVGAMesaInit: invalid GraphMode (ModeX)");
100 if (!SVGAInfo
->bytesperpixel
)
102 fprintf(stderr
,"1 / 4 bit color not implemented...");
104 SVGAlog("SVGAMesaInit: invalid GraphMode (1 or 4 bit)");
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;
114 SVGABuffer
.BufferSize
=SVGAInfo
->linewidth
*SVGAInfo
->height
;
116 sprintf(cbuf
,"SVGAMesaInit: double buffer info.\n" \
122 SVGABuffer
.Depth
,GraphMode
,SVGAInfo
->linewidth
, \
123 SVGAInfo
->height
,SVGABuffer
.BufferSize
);
126 SVGABuffer
.FrontBuffer
=(void*)malloc(SVGABuffer
.BufferSize
+ 4);
127 if (!SVGABuffer
.FrontBuffer
) {
129 fprintf(stderr
,"Not enough RAM for FRONT_LEFT_BUFFER...");
131 SVGAlog("SVGAMesaInit: Not enough RAM (front buffer)");
137 sprintf(cbuf
,"SVGAMesaInit: FrontBuffer - %p",SVGABuffer
.FrontBuffer
);
140 SVGABuffer
.BackBuffer
=(void*)malloc(SVGABuffer
.BufferSize
+ 4);
141 if (!SVGABuffer
.BackBuffer
) {
143 free(SVGABuffer
.FrontBuffer
);
144 fprintf(stderr
,"Not enough RAM for BACK_LEFT_BUFFER...");
146 SVGAlog("SVGAMesaInit: Not enough RAM (back buffer)");
152 sprintf(cbuf
,"SVGAMesaInit: BackBuffer - %p",SVGABuffer
.BackBuffer
);
156 vga_setmode(GraphMode
);
157 SVGABuffer
.VideoRam
=vga_getgraphmem();
159 sprintf(cbuf
,"SVGAMesaInit: VRAM - %p",SVGABuffer
.VideoRam
);
161 sprintf(cbuf
,"SVGAMesaInit: done. (Mode %d)",GraphMode
);
165 SVGABuffer
.DrawBuffer
= SVGABuffer
.BackBuffer
;
166 SVGABuffer
.ReadBuffer
= SVGABuffer
.BackBuffer
;
171 int SVGAMesaClose( void )
174 free(SVGABuffer
.FrontBuffer
);
175 free(SVGABuffer
.BackBuffer
);
179 void SVGAMesaSetCI(int ndx
, GLubyte red
, GLubyte green
, GLubyte blue
)
182 vga_setpalette(ndx
, red
>>2, green
>>2, blue
>>2);
185 /**********************************************************************/
186 /***** Miscellaneous functions *****/
187 /**********************************************************************/
189 static void copy_buffer( const GLubyte
* buffer
) {
190 int size
= SVGABuffer
.BufferSize
, page
= 0;
193 sprintf(cbuf
,"copy_buffer: copy %p to %p",buffer
,SVGABuffer
.VideoRam
);
200 memcpy(SVGABuffer
.VideoRam
,buffer
,0x10000);
203 memcpy(SVGABuffer
.VideoRam
,buffer
,size
& 0xffff);
209 static void get_buffer_size( GLframebuffer
*buffer
, GLuint
*width
, GLuint
*height
)
211 *width
= SVGAMesa
->width
= vga_getxdim();
212 *height
= SVGAMesa
->height
= vga_getydim();
216 * We only implement this function as a mechanism to check if the
217 * framebuffer size has changed (and update corresponding state).
219 static void viewport(GLcontext
*ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
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
);
229 static void set_buffer( GLcontext
*ctx
, GLframebuffer
*colorBuffer
,
232 /* We can ignore colorBuffer since we don't support a MakeCurrentRead()
237 if (buffer
== GL_FRONT_LEFT
) {
238 SVGABuffer
.ReadBuffer
= SVGABuffer
.FrontBuffer
;
239 SVGABuffer
.DrawBuffer
= SVGABuffer
.FrontBuffer
;
242 /* vga_waitretrace(); */
243 copy_buffer(SVGABuffer
.FrontBuffer
);
244 tmpptr
=SVGABuffer
.BackBuffer
;
245 SVGABuffer
.BackBuffer
=SVGABuffer
.FrontBuffer
;
246 SVGABuffer
.FrontBuffer
=tmpptr
;
249 else if (buffer
== GL_BACK_LEFT
) {
250 SVGABuffer
.ReadBuffer
= SVGABuffer
.BackBuffer
;
251 SVGABuffer
.DrawBuffer
= SVGABuffer
.BackBuffer
;
253 /* vga_waitretrace(); */
254 copy_buffer(SVGABuffer
.BackBuffer
);
259 /**********************************************************************/
261 /**********************************************************************/
263 static void svgamesa_update_state( GLcontext
*ctx
, GLuint new_state
)
265 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference( ctx
);
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! */
270 ctx
->Driver
.UpdateState
= svgamesa_update_state
;
272 ctx
->Driver
.GetBufferSize
= get_buffer_size
;
273 ctx
->Driver
.Viewport
= viewport
;
275 /* Fill in the swrast driver interface:
277 swdd
->SetBuffer
= set_buffer
;
279 switch (SVGABuffer
.Depth
) {
280 case 8: ctx
->Driver
.ClearIndex
= __clear_index8
;
281 ctx
->Driver
.Clear
= __clear8
;
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
;
291 SVGAlog("SVGAUpdateState: 8 bit mode.");
295 case 15: ctx
->Driver
.ClearColor
= __clear_color15
;
296 ctx
->Driver
.Clear
= __clear15
;
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
;
305 SVGAlog("SVGAUpdateState: 15 bit mode.");
308 case 16: ctx
->Driver
.ClearColor
= __clear_color16
;
309 ctx
->Driver
.Clear
= __clear16
;
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
;
319 SVGAlog("SVGAUpdateState: 16 bit mode.");
321 case 24: ctx
->Driver
.ClearColor
= __clear_color24
;
322 ctx
->Driver
.Clear
= __clear24
;
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
;
332 SVGAlog("SVGAUpdateState: 32 bit mode.");
334 case 32: ctx
->Driver
.ClearColor
= __clear_color32
;
335 ctx
->Driver
.Clear
= __clear32
;
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
;
347 * Create a new VGA/Mesa context and return a handle to it.
349 SVGAMesaContext
SVGAMesaCreateContext( GLboolean doubleBuffer
)
354 GLfloat redscale
, greenscale
, bluescale
, alphascale
;
356 GLint redbits
, greenbits
, bluebits
, alphabits
;
358 /* determine if we're in RGB or color index mode */
359 if ((SVGABuffer
.Depth
==32) || (SVGABuffer
.Depth
==24)) {
361 redscale
= greenscale
= bluescale
= alphascale
= 255.0;
362 redbits
= greenbits
= bluebits
= 8;
366 else if (SVGABuffer
.Depth
==8) {
368 redscale
= greenscale
= bluescale
= alphascale
= 0.0;
369 redbits
= greenbits
= bluebits
= alphabits
= 0;
372 else if (SVGABuffer
.Depth
==15) {
374 redscale
= greenscale
= bluescale
= alphascale
= 31.0;
375 redbits
= greenbits
= bluebits
= 5;
379 else if (SVGABuffer
.Depth
==16) {
381 redscale
= bluescale
= alphascale
= 31.0;
383 redbits
= bluebits
= 5;
389 ctx
= (SVGAMesaContext
) calloc( 1, sizeof(struct svgamesa_context
) );
394 ctx
->gl_vis
= _mesa_create_visual( rgb_flag
,
396 GL_FALSE
, /* stereo */
401 8, /* stencil_size */
402 16, 16, 16, 16, /* accum_size */
406 ctx
->gl_ctx
= _mesa_create_context( ctx
->gl_vis
,
407 NULL
, /* share list context */
408 (void *) ctx
, GL_FALSE
);
410 _mesa_enable_sw_extensions(ctx
->gl_ctx
);
411 _mesa_enable_1_3_extensions(ctx
->gl_ctx
);
413 _mesa_init_driver_functions(&ctx
->Driver
);
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 );
421 ctx
->width
= ctx
->height
= 0; /* temporary until first "make-current" */
427 * Destroy the given VGA/Mesa context.
429 void SVGAMesaDestroyContext( SVGAMesaContext ctx
)
433 _mesa_destroy_visual( ctx
->gl_vis
);
434 _mesa_destroy_context( ctx
->gl_ctx
);
444 * Make the specified VGA/Mesa context the current one.
446 void SVGAMesaMakeCurrent( SVGAMesaContext ctx
)
450 svgamesa_update_state( ctx
->gl_ctx
, ~0 );
451 _mesa_make_current( ctx
->gl_ctx
, ctx
->gl_buffer
);
453 if (ctx
->width
==0 || ctx
->height
==0) {
454 ctx
->width
= vga_getxdim();
455 ctx
->height
= vga_getydim();
461 * Return a handle to the current VGA/Mesa context.
463 SVGAMesaContext
SVGAMesaGetCurrentContext( void )
469 * Swap front/back buffers for current context if double buffered.
471 void SVGAMesaSwapBuffers( void )
477 /* vga_waitretrace(); */
478 copy_buffer(SVGABuffer
.BackBuffer
);
481 _mesa_notifySwapBuffers( SVGAMesa
->gl_ctx
);
482 if (SVGAMesa
->gl_vis
->doubleBufferMode
)
486 sprintf(cbuf
,"SVGAMesaSwapBuffers : Swapping...");
488 #endif /* SVGA_DEBUG */
490 tmpptr
=SVGABuffer
.BackBuffer
;
491 SVGABuffer
.BackBuffer
=SVGABuffer
.FrontBuffer
;
492 SVGABuffer
.FrontBuffer
=tmpptr
;
495 sprintf(cbuf
,"SVGAMesaSwapBuffers : WriteBuffer : %p\n"
496 " Readbuffer : %p", \
497 SVGABuffer
.BackBuffer
, SVGABuffer
.FrontBuffer
);
499 #endif /* SVGA_DEBUG */
506 * Need this to provide at least one external definition when SVGA is
507 * not defined on the compiler command line.
509 extern int gl_svga_dummy_function(void);
510 int gl_svga_dummy_function(void)