blob: 01be301224215e6d991516b54541cbd43c445b0f [file] [log] [blame]
Brian Pauldb41d2e2002-02-12 03:24:56 +00001/*
2 * Mesa 3-D graphics library
3 * Version: 4.0
4 *
5 * Copyright (C) 1999 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25/*
26 * DOS/DJGPP device driver v0.1 for Mesa 4.0
27 *
28 * Copyright (C) 2002 - Borca Daniel
29 * Email : dborca@yahoo.com
30 * Web : http://www.geocities.com/dborca
31 */
32
33
34#ifdef PC_HEADER
35#include "all.h"
36#else
37#include "glheader.h"
38#include "context.h"
39#include "GL/dmesa.h"
40#include "matrix.h"
41#include "texformat.h"
42#include "texstore.h"
43#include "array_cache/acache.h"
44#include "swrast/swrast.h"
45#include "swrast_setup/swrast_setup.h"
46#include "tnl/tnl.h"
47#include "tnl/t_context.h"
48#include "tnl/t_pipeline.h"
49#endif
50
51#include "dvesa.h"
52#include "dmesaint.h"
53
54
55
56/*
57 * In C++ terms, this class derives from the GLvisual class.
58 * Add system-specific fields to it.
59 */
60struct dmesa_visual {
61 GLvisual *gl_visual;
62 GLboolean db_flag; /* double buffered? */
63 GLboolean rgb_flag; /* RGB mode? */
64 GLuint depth; /* bits per pixel (1, 8, 24, etc) */
65};
66
67/*
68 * In C++ terms, this class derives from the GLframebuffer class.
69 * Add system-specific fields to it.
70 */
71struct dmesa_buffer {
72 GLframebuffer *gl_buffer; /* The depth, stencil, accum, etc buffers */
73 void *the_window; /* your window handle, etc */
74
75 int width, height; /* size in pixels */
76 int xpos, ypos; /* buffer position */
77 int xsize, len; /* number of bytes in a line, then total */
78 int delta; /* used to wrap around */
79 int offset; /* offset in video */
80 struct dvmode *video;
81};
82
83/*
84 * In C++ terms, this class derives from the GLcontext class.
85 * Add system-specific fields to it.
86 */
87struct dmesa_context {
88 GLcontext *gl_ctx; /* the core library context */
89 DMesaVisual visual;
90 DMesaBuffer Buffer;
91 GLuint ClearColor;
92 /* etc... */
93};
94
95
96
97static void dmesa_update_state (GLcontext *ctx, GLuint new_state);
98
99
100
101/**********************************************************************/
102/***** Read/Write pixels *****/
103/**********************************************************************/
104
105
106
107WRITE_RGBA_SPAN(15)
108WRITE_RGBA_SPAN(16)
109WRITE_RGBA_SPAN(24)
110WRITE_RGBA_SPAN(32)
111
112WRITE_RGB_SPAN(15)
113WRITE_RGB_SPAN(16)
114WRITE_RGB_SPAN(24)
115WRITE_RGB_SPAN(32)
116
117WRITE_MONO_RGBA_SPAN(15)
118WRITE_MONO_RGBA_SPAN(16)
119WRITE_MONO_RGBA_SPAN(24)
120WRITE_MONO_RGBA_SPAN(32)
121
122READ_RGBA_SPAN(15)
123READ_RGBA_SPAN(16)
124READ_RGBA_SPAN(24)
125READ_RGBA_SPAN(32)
126
127WRITE_RGBA_PIXELS(15)
128WRITE_RGBA_PIXELS(16)
129WRITE_RGBA_PIXELS(24)
130WRITE_RGBA_PIXELS(32)
131
132WRITE_MONO_RGBA_PIXELS(15)
133WRITE_MONO_RGBA_PIXELS(16)
134WRITE_MONO_RGBA_PIXELS(24)
135WRITE_MONO_RGBA_PIXELS(32)
136
137READ_RGBA_PIXELS(15)
138READ_RGBA_PIXELS(16)
139READ_RGBA_PIXELS(24)
140READ_RGBA_PIXELS(32)
141
142
143
144/**********************************************************************/
145/***** Miscellaneous device driver funcs *****/
146/**********************************************************************/
147
148
149
150static void clear_color (GLcontext *ctx, const GLchan color[4])
151{
152 DMesaContext c = (DMesaContext)ctx->DriverCtx;
153 c->ClearColor = dv_color(color);
154}
155
156
157
158static void clear (GLcontext *ctx, GLbitfield mask, GLboolean all,
159 GLint x, GLint y, GLint width, GLint height)
160{
161 DMesaContext c = (DMesaContext)ctx->DriverCtx;
162 const GLuint *colorMask = (GLuint *)&ctx->Color.ColorMask;
163 DMesaBuffer b = c->Buffer;
164
165/*
166 * Clear the specified region of the buffers indicated by 'mask'
167 * using the clear color or index as specified by one of the two
168 * functions above.
169 * If all==GL_TRUE, clear whole buffer, else just clear region defined
170 * by x,y,width,height
171 */
172
173 /* we can't handle color or index masking */
174 if (*colorMask==0xffffffff && ctx->Color.IndexMask==0xffffffff) {
175 if (mask&DD_BACK_LEFT_BIT) {
176 if (all) {
177 dv_clear_virtual(b->the_window, b->len, c->ClearColor);
178 } else {
179 dv_fillrect(b->the_window, b->width, x, y, width, height, c->ClearColor);
180 }
181 mask &= ~DD_BACK_LEFT_BIT;
182 }
183 }
184
185 if (mask) {
186 _swrast_Clear(ctx, mask, all, x, y, width, height);
187 }
188}
189
190
191
192/*
193 * Set the current reading buffer.
194 */
195static void set_read_buffer (GLcontext *ctx, GLframebuffer *buffer,
196 GLenum mode)
197{
198/*
199 DMesaContext c = (DMesaContext)ctx->DriverCtx;
200 dmesa_update_state(ctx);
201*/
202}
203
204
205
206/*
207 * Set the destination/draw buffer.
208 */
209static GLboolean set_draw_buffer (GLcontext *ctx, GLenum mode)
210{
211 if (mode==GL_BACK_LEFT) {
212 return GL_TRUE;
213 } else {
214 return GL_FALSE;
215 }
216}
217
218
219
220/*
221 * Return the width and height of the current buffer.
222 * If anything special has to been done when the buffer/window is
223 * resized, do it now.
224 */
225static void get_buffer_size (GLcontext *ctx, GLuint *width, GLuint *height)
226{
227 DMesaContext c = (DMesaContext)ctx->DriverCtx;
228
229 *width = c->Buffer->width;
230 *height = c->Buffer->height;
231}
232
233
234
235static const GLubyte* get_string (GLcontext *ctx, GLenum name)
236{
237 switch (name) {
238 case GL_RENDERER:
239 return (const GLubyte *)"DOS Mesa";
240 default:
241 return NULL;
242 }
243}
244
245
246
247/**********************************************************************/
248/***** Miscellaneous device driver funcs *****/
249/***** Note that these functions are mandatory *****/
250/**********************************************************************/
251
252
253
254/* OPTIONAL FUNCTION: implements glFinish if possible */
255static void finish (GLcontext *ctx)
256{
257/*
258 DMesaContext c = (DMesaContext)ctx->DriverCtx;
259*/
260}
261
262
263
264/* OPTIONAL FUNCTION: implements glFlush if possible */
265static void flush (GLcontext *ctx)
266{
267/*
268 DMesaContext c = (DMesaContext)ctx->DriverCtx;
269*/
270}
271
272
273
274/**********************************************************************/
275/**********************************************************************/
276
277
278
279/* Setup pointers and other driver state that is constant for the life
280 * of a context.
281 */
282void dmesa_init_pointers (GLcontext *ctx)
283{
284 TNLcontext *tnl;
285
286 ctx->Driver.UpdateState = dmesa_update_state;
287
288 ctx->Driver.GetString = get_string;
289 ctx->Driver.GetBufferSize = get_buffer_size;
290 ctx->Driver.Flush = flush;
291 ctx->Driver.Finish = finish;
292
293 /* Software rasterizer pixel paths:
294 */
295 ctx->Driver.Accum = _swrast_Accum;
296 ctx->Driver.Bitmap = _swrast_Bitmap;
297 ctx->Driver.Clear = clear;
298 ctx->Driver.ResizeBuffersMESA = _swrast_alloc_buffers;
299 ctx->Driver.CopyPixels = _swrast_CopyPixels;
300 ctx->Driver.DrawPixels = _swrast_DrawPixels;
301 ctx->Driver.ReadPixels = _swrast_ReadPixels;
302
303 /* Software texture functions:
304 */
305 ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
306 ctx->Driver.TexImage1D = _mesa_store_teximage1d;
307 ctx->Driver.TexImage2D = _mesa_store_teximage2d;
308 ctx->Driver.TexImage3D = _mesa_store_teximage3d;
309 ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
310 ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
311 ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
312 ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
313
314 ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
315 ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
316 ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
317 ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
318 ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
319
320 ctx->Driver.BaseCompressedTexFormat = _mesa_base_compressed_texformat;
321 ctx->Driver.CompressedTextureSize = _mesa_compressed_texture_size;
322 ctx->Driver.GetCompressedTexImage = _mesa_get_compressed_teximage;
323
324 /* Swrast hooks for imaging extensions:
325 */
326 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
327 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
328 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
329 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
330
331 /* Statechange callbacks:
332 */
333 ctx->Driver.SetDrawBuffer = set_draw_buffer;
334 ctx->Driver.ClearColor = clear_color;
335
336 /* Initialize the TNL driver interface:
337 */
338 tnl = TNL_CONTEXT(ctx);
339 tnl->Driver.RunPipeline = _tnl_run_pipeline;
340
341 /* Install swsetup for tnl->Driver.Render.*:
342 */
343 _swsetup_Wakeup(ctx);
344}
345
346
347
348static void dmesa_update_state (GLcontext *ctx, GLuint new_state)
349{
350 DMesaContext c = (DMesaContext)ctx->DriverCtx;
351 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
352
353 /* Initialize all the pointers in the DD struct. Do this whenever */
354 /* a new context is made current or we change buffers via set_buffer! */
355
356 _swrast_InvalidateState(ctx, new_state);
357 _swsetup_InvalidateState(ctx, new_state);
358 _ac_InvalidateState(ctx, new_state);
359 _tnl_InvalidateState(ctx, new_state);
360
361 swdd->SetReadBuffer = set_read_buffer;
362
363 /* RGB(A) span/pixel functions */
364 switch (c->visual->depth) {
365 case 15:
366 swdd->WriteRGBASpan = write_rgba_span_15;
367 swdd->WriteRGBSpan = write_rgb_span_15;
368 swdd->WriteMonoRGBASpan = write_mono_rgba_span_15;
369 swdd->WriteRGBAPixels = write_rgba_pixels_15;
370 swdd->WriteMonoRGBAPixels = write_mono_rgba_pixels_15;
371 swdd->ReadRGBASpan = read_rgba_span_15;
372 swdd->ReadRGBAPixels = read_rgba_pixels_15;
373 break;
374 case 16:
375 swdd->WriteRGBASpan = write_rgba_span_16;
376 swdd->WriteRGBSpan = write_rgb_span_16;
377 swdd->WriteMonoRGBASpan = write_mono_rgba_span_16;
378 swdd->WriteRGBAPixels = write_rgba_pixels_16;
379 swdd->WriteMonoRGBAPixels = write_mono_rgba_pixels_16;
380 swdd->ReadRGBASpan = read_rgba_span_16;
381 swdd->ReadRGBAPixels = read_rgba_pixels_16;
382 break;
383 case 24:
384 swdd->WriteRGBASpan = write_rgba_span_24;
385 swdd->WriteRGBSpan = write_rgb_span_24;
386 swdd->WriteMonoRGBASpan = write_mono_rgba_span_24;
387 swdd->WriteRGBAPixels = write_rgba_pixels_24;
388 swdd->WriteMonoRGBAPixels = write_mono_rgba_pixels_24;
389 swdd->ReadRGBASpan = read_rgba_span_24;
390 swdd->ReadRGBAPixels = read_rgba_pixels_24;
391 break;
392 case 32:
393 swdd->WriteRGBASpan = write_rgba_span_32;
394 swdd->WriteRGBSpan = write_rgb_span_32;
395 swdd->WriteMonoRGBASpan = write_mono_rgba_span_32;
396 swdd->WriteRGBAPixels = write_rgba_pixels_32;
397 swdd->WriteMonoRGBAPixels = write_mono_rgba_pixels_32;
398 swdd->ReadRGBASpan = read_rgba_span_32;
399 swdd->ReadRGBAPixels = read_rgba_pixels_32;
400 break;
401 }
402}
403
404
405
406/**********************************************************************/
407/***** DMesa Public API Functions *****/
408/**********************************************************************/
409
410
411
412/*
413 * The exact arguments to this function will depend on your window system
414 */
415DMesaVisual DMesaCreateVisual (GLint colDepth, GLboolean dbFlag,
416 GLint depthSize, GLint stencilSize,
417 GLint accumSize)
418{
419 DMesaVisual v;
420 GLint redBits, greenBits, blueBits, alphaBits;
421
422 if (!dbFlag) {
423 return NULL;
424 }
425 switch (colDepth) {
426 case 15:
427 redBits = 5;
428 greenBits = 5;
429 blueBits = 5;
430 break;
431 case 16:
432 redBits = 5;
433 greenBits = 6;
434 blueBits = 5;
435 break;
436 case 24:
437 case 32:
438 redBits = 8;
439 greenBits = 8;
440 blueBits = 8;
441 break;
442 default:
443 return NULL;
444 }
445 alphaBits = 8;
446
447 if ((v=(DMesaVisual)calloc(1, sizeof(struct dmesa_visual)))!=NULL) {
448 /* Create core visual */
449 v->gl_visual = _mesa_create_visual(colDepth>8, /* rgb */
450 dbFlag,
451 GL_FALSE, /* stereo */
452 redBits,
453 greenBits,
454 blueBits,
455 alphaBits,
456 0, /* indexBits */
457 depthSize,
458 stencilSize,
459 accumSize, /* accumRed */
460 accumSize, /* accumGreen */
461 accumSize, /* accumBlue */
462 alphaBits?accumSize:0, /* accumAlpha */
463 1); /* numSamples */
464
465 v->depth = colDepth;
466 v->db_flag = dbFlag;
467 }
468
469 return v;
470}
471
472
473
474void DMesaDestroyVisual (DMesaVisual v)
475{
476 _mesa_destroy_visual(v->gl_visual);
477 free(v);
478}
479
480
481
482DMesaBuffer DMesaCreateBuffer (DMesaVisual visual,
483 GLint width, GLint height,
484 GLint xpos, GLint ypos)
485{
486 DMesaBuffer b;
487
488 if ((b=(DMesaBuffer)calloc(1, sizeof(struct dmesa_buffer)))!=NULL) {
489 if (visual->db_flag) {
490 if ((b->the_window=calloc(1, width*height*((visual->depth+7)/8)))==NULL) {
491 return NULL;
492 }
493 }
494
495 b->gl_buffer = _mesa_create_framebuffer(visual->gl_visual,
496 visual->gl_visual->depthBits > 0,
497 visual->gl_visual->stencilBits > 0,
498 visual->gl_visual->accumRedBits > 0,
499 visual->gl_visual->alphaBits > 0);
500 b->width = width;
501 b->height = height;
502 b->xpos = xpos;
503 b->ypos = ypos;
504 }
505
506 return b;
507}
508
509
510
511void DMesaDestroyBuffer (DMesaBuffer b)
512{
513 free(b->the_window);
514 _mesa_destroy_framebuffer(b->gl_buffer);
515 free(b);
516}
517
518
519
520DMesaContext DMesaCreateContext (DMesaVisual visual,
521 DMesaContext share)
522{
523 DMesaContext c;
524 GLboolean direct = GL_FALSE;
525
526 if ((c=(DMesaContext)calloc(1, sizeof(struct dmesa_context)))!=NULL) {
527 c->gl_ctx = _mesa_create_context(visual->gl_visual,
528 share ? share->gl_ctx : NULL,
529 (void *)c, direct);
530
531 /* you probably have to do a bunch of other initializations here. */
532 c->visual = visual;
533
534 /* Initialize the software rasterizer and helper modules.
535 */
536 _swrast_CreateContext(c->gl_ctx);
537 _ac_CreateContext(c->gl_ctx);
538 _tnl_CreateContext(c->gl_ctx);
539 _swsetup_CreateContext(c->gl_ctx);
540 dmesa_init_pointers(c->gl_ctx);
541 }
542
543 return c;
544}
545
546
547
548void DMesaDestroyContext (DMesaContext c)
549{
550 _mesa_destroy_context(c->gl_ctx);
551 free(c);
552}
553
554
555
556/*
557 * Make the specified context and buffer the current one.
558 */
559GLboolean DMesaMakeCurrent (DMesaContext c, DMesaBuffer b)
560{
561 if (c&&b) {
562 c->Buffer = b;
563 if ((b->video=dv_select_mode(b->xpos, b->ypos, b->width, b->height, c->visual->depth, &b->delta, &b->offset))==NULL) {
564 return GL_FALSE;
565 }
566
567 b->xsize = b->width*((c->visual->depth+7)/8);
568 b->len = b->xsize*b->height;
569
570 dmesa_update_state(c->gl_ctx, 0);
571 _mesa_make_current(c->gl_ctx, b->gl_buffer);
572 if (c->gl_ctx->Viewport.Width==0) {
573 /* initialize viewport to window size */
574 _mesa_Viewport(0, 0, c->Buffer->width, c->Buffer->height);
575 }
576 } else {
577 /* Detach */
578 _mesa_make_current(NULL, NULL);
579 }
580
581 return GL_TRUE;
582}
583
584
585
586void DMesaSwapBuffers (DMesaBuffer b)
587{
588 /* copy/swap back buffer to front if applicable */
589 if (b->the_window) {
590 dv_dump_virtual(b->the_window, b->xsize, b->height, b->offset, b->delta);
591 }
592}