1
/****************************************************************************
3
* Mesa 3-D graphics library
4
* Direct3D Driver Interface
6
* ========================================================================
8
* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved.
10
* Permission is hereby granted, free of charge, to any person obtaining a
11
* copy of this software and associated documentation files (the "Software"),
12
* to deal in the Software without restriction, including without limitation
13
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
14
* and/or sell copies of the Software, and to permit persons to whom the
15
* Software is furnished to do so, subject to the following conditions:
17
* The above copyright notice and this permission notice shall be included
18
* in all copies or substantial portions of the Software.
20
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23
* SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
25
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
* ======================================================================
31
* Environment: Windows 9x/2000/XP/XBox (Win32)
33
* Description: Mesa Software WGL (WindowsGL)
35
****************************************************************************/
38
#define GL_GLEXT_PROTOTYPES
48
#include "extensions.h"
54
#include "texformat.h"
57
#include "array_cache/acache.h"
58
#include "swrast/swrast.h"
59
#include "swrast_setup/swrast_setup.h"
60
#include "swrast/s_context.h"
61
#include "swrast/s_depth.h"
62
#include "swrast/s_lines.h"
63
#include "swrast/s_triangle.h"
64
#include "swrast/s_trispan.h"
66
#include "tnl/t_context.h"
67
#include "tnl/t_pipeline.h"
69
#include "dglcontext.h"
70
#include "gld_driver.h"
72
//---------------------------------------------------------------------------
73
//---------------------------------------------------------------------------
75
DGL_pixelFormat pfTemplateMesaSW =
78
sizeof(PIXELFORMATDESCRIPTOR), // Size of the data structure
79
1, // Structure version - should be 1
81
PFD_DRAW_TO_WINDOW | // The buffer can draw to a window or device surface.
82
PFD_DRAW_TO_BITMAP | // The buffer can draw to a bitmap. (DaveM)
83
PFD_SUPPORT_GDI | // The buffer supports GDI drawing. (DaveM)
84
PFD_SUPPORT_OPENGL | // The buffer supports OpenGL drawing.
85
PFD_DOUBLEBUFFER | // The buffer is double-buffered.
86
0, // Placeholder for easy commenting of above flags
87
PFD_TYPE_RGBA, // Pixel type RGBA.
88
32, // Total colour bitplanes (excluding alpha bitplanes)
89
8, 0, // Red bits, shift
90
8, 8, // Green bits, shift
91
8, 16, // Blue bits, shift
92
8, 24, // Alpha bits, shift (destination alpha)
93
64, // Accumulator bits (total)
94
16, 16, 16, 16, // Accumulator bits: Red, Green, Blue, Alpha
97
0, // Number of auxiliary buffers
99
0, // Specifies the number of overlay and underlay planes.
101
0, // Specifies the transparent color or index of an underlay plane.
107
//---------------------------------------------------------------------------
109
//---------------------------------------------------------------------------
116
static GLD_extension GLD_extList[] = {
117
#ifdef GL_EXT_polygon_offset
118
{ (PROC)glPolygonOffsetEXT, "glPolygonOffsetEXT" },
120
{ (PROC)glBlendEquationEXT, "glBlendEquationEXT" },
121
{ (PROC)glBlendColorEXT, "glBlendColorExt" },
122
{ (PROC)glVertexPointerEXT, "glVertexPointerEXT" },
123
{ (PROC)glNormalPointerEXT, "glNormalPointerEXT" },
124
{ (PROC)glColorPointerEXT, "glColorPointerEXT" },
125
{ (PROC)glIndexPointerEXT, "glIndexPointerEXT" },
126
{ (PROC)glTexCoordPointerEXT, "glTexCoordPointer" },
127
{ (PROC)glEdgeFlagPointerEXT, "glEdgeFlagPointerEXT" },
128
{ (PROC)glGetPointervEXT, "glGetPointervEXT" },
129
{ (PROC)glArrayElementEXT, "glArrayElementEXT" },
130
{ (PROC)glDrawArraysEXT, "glDrawArrayEXT" },
131
{ (PROC)glAreTexturesResidentEXT, "glAreTexturesResidentEXT" },
132
{ (PROC)glBindTextureEXT, "glBindTextureEXT" },
133
{ (PROC)glDeleteTexturesEXT, "glDeleteTexturesEXT" },
134
{ (PROC)glGenTexturesEXT, "glGenTexturesEXT" },
135
{ (PROC)glIsTextureEXT, "glIsTextureEXT" },
136
{ (PROC)glPrioritizeTexturesEXT, "glPrioritizeTexturesEXT" },
137
{ (PROC)glCopyTexSubImage3DEXT, "glCopyTexSubImage3DEXT" },
138
{ (PROC)glTexImage3DEXT, "glTexImage3DEXT" },
139
{ (PROC)glTexSubImage3DEXT, "glTexSubImage3DEXT" },
140
{ (PROC)glPointParameterfEXT, "glPointParameterfEXT" },
141
{ (PROC)glPointParameterfvEXT, "glPointParameterfvEXT" },
142
{ (PROC)glLockArraysEXT, "glLockArraysEXT" },
143
{ (PROC)glUnlockArraysEXT, "glUnlockArraysEXT" },
147
//---------------------------------------------------------------------------
148
// WMesa Internal Functions
149
//---------------------------------------------------------------------------
151
#define PAGE_FILE 0xffffffff
154
#define REDSHIFT 0x00
155
#define GREENBITS 0x03
156
#define GREENSHIFT 0x03
157
#define BLUEBITS 0x02
158
#define BLUESHIFT 0x06
160
typedef struct _dibSection {
165
} WMDIBSECTION, *PWMDIBSECTION;
167
typedef struct wmesa_context {
171
HPALETTE hOldPalette;
176
// 3D projection stuff
184
GLboolean db_flag; //* double buffered?
185
GLboolean rgb_flag; //* RGB mode?
186
GLboolean dither_flag; //* use dither when 256 color mode for RGB?
187
GLuint depth; //* bits per pixel (1, 8, 24, etc)
188
ULONG pixel; // current color index or RGBA pixel value
189
ULONG clearpixel; //* pixel for clearing the color buffers
190
PBYTE ScreenMem; // WinG memory
191
BITMAPINFO *IndexFormat;
192
HPALETTE hPal; // Current Palette
193
HPALETTE hPalHalfTone;
200
HBITMAP Old_Compat_BM;
201
HBITMAP Compat_BM; // Bitmap for double buffering
213
// We always double-buffer, for performance reasons, but
214
// we need to know which of SwapBuffers() or glFlush() to
215
// handle. If we're emulating, then we update on Flush(),
216
// otherwise we update on SwapBufers(). KeithH
217
BOOL bEmulateSingleBuffer;
218
} WMesaContext, *PWMC;
220
#define GLD_GET_WMESA_DRIVER(c) (WMesaContext*)(c)->glPriv
223
GLint stereo_flag = 0 ;
225
/* If we are double-buffering, we want to get the DC for the
226
* off-screen DIB, otherwise the DC for the window.
228
#define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
231
#define FLIP(Y) (Current->height-(Y)-1)
233
struct DISPLAY_OPTIONS {
240
struct DISPLAY_OPTIONS displayOptions;
242
//---------------------------------------------------------------------------
244
static unsigned char threeto8[8] = {
245
0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
248
static unsigned char twoto8[4] = {
252
static unsigned char oneto8[2] = {
256
//---------------------------------------------------------------------------
258
BYTE DITHER_RGB_2_8BIT( int red, int green, int blue, int pixel, int scanline)
260
char unsigned redtemp, greentemp, bluetemp, paletteindex;
262
//*** now, look up each value in the halftone matrix
263
//*** using an 8x8 ordered dither.
264
redtemp = aDividedBy51[red]
265
+ (aModulo51[red] > aHalftone8x8[(pixel%8)*8
267
greentemp = aDividedBy51[(char unsigned)green]
268
+ (aModulo51[green] > aHalftone8x8[
269
(pixel%8)*8 + scanline%8]);
270
bluetemp = aDividedBy51[(char unsigned)blue]
271
+ (aModulo51[blue] > aHalftone8x8[
272
(pixel%8)*8 +scanline%8]);
274
//*** recombine the halftoned rgb values into a palette index
276
redtemp + aTimes6[greentemp] + aTimes36[bluetemp];
278
//*** and translate through the wing halftone palette
279
//*** translation vector to give the correct value.
280
return aWinGHalftoneTranslation[paletteindex];
283
//---------------------------------------------------------------------------
285
static unsigned char componentFromIndex(UCHAR i, UINT nbits, UINT shift)
302
return threeto8[val];
309
//---------------------------------------------------------------------------
312
void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
314
WMesaContext *Current = pwc;
316
// Test for invalid scanline parameter. KeithH
317
if ((iScanLine < 0) || (iScanLine >= pwc->height))
320
if (Current->db_flag) {
321
LPBYTE lpb = pwc->pbPixels;
322
UINT nBypp = pwc->cColorBits >> 3;
323
UINT nOffset = iPixel % nBypp;
325
lpb += pwc->ScanWidth * iScanLine;
326
lpb += iPixel * nBypp;
330
*lpb = DITHER_RGB_2_8BIT(r,g,b,iScanLine,iPixel);
335
*((LPWORD)lpb) = BGR16(r,g,b);
337
*((LPDWORD)lpb) = BGR24(r,g,b);
339
*((LPDWORD)lpb) = BGR32(r,g,b);
342
SetPixel(Current->hDC, iPixel, iScanLine, RGB(r,g,b));
346
//---------------------------------------------------------------------------
348
void wmCreateDIBSection(
350
PWMC pwc, // handle of device context
351
CONST BITMAPINFO *pbmi, // bitmap size, format, and color data
352
UINT iUsage // color data type indicator: RGB values or palette indices
357
UINT nBypp = pwc->cColorBits / 8;
360
dwScanWidth = (((pwc->ScanWidth * nBypp)+ 3) & ~3);
362
pwc->ScanWidth =pwc->pitch = dwScanWidth;
365
pwc->ScanWidth = 2* pwc->pitch;
367
dwSize = sizeof(BITMAPINFO) + (dwScanWidth * pwc->height);
369
pwc->dib.hFileMap = CreateFileMapping((HANDLE)PAGE_FILE,
371
PAGE_READWRITE | SEC_COMMIT,
376
if (!pwc->dib.hFileMap)
379
pwc->dib.base = MapViewOfFile(pwc->dib.hFileMap,
386
CloseHandle(pwc->dib.hFileMap);
391
CopyMemory(pwc->dib.base, pbmi, sizeof(BITMAPINFO));
393
hic = CreateIC("display", NULL, NULL, NULL);
394
pwc->dib.hDC = CreateCompatibleDC(hic);
397
pwc->hbmDIB = CreateDIBSection(hic,
399
(iUsage ? DIB_PAL_COLORS : DIB_RGB_COLORS),
403
pwc->ScreenMem = pwc->addrOffScreen = pwc->pbPixels;
404
pwc->hOldBitmap = SelectObject(pwc->dib.hDC, pwc->hbmDIB);
412
//---------------------------------------------------------------------------
414
void wmCreatePalette( PWMC pwdc )
416
/* Create a compressed and re-expanded 3:3:2 palette */
419
BYTE rb, rs, gb, gs, bb, bs;
421
pwdc->nColors = 0x100;
423
pPal = (PLOGPALETTE)malloc(sizeof(LOGPALETTE) +
424
pwdc->nColors * sizeof(PALETTEENTRY));
425
memset( pPal, 0, sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY) );
427
pPal->palVersion = 0x300;
438
/* Need to make two palettes: one for the screen DC and one for the DIB. */
439
pPal->palNumEntries = pwdc->nColors;
440
for (i = 0; i < pwdc->nColors; i++) {
441
pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
442
pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
443
pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
444
pPal->palPalEntry[i].peFlags = 0;
446
pwdc->hGLPalette = CreatePalette( pPal );
447
pwdc->hPalette = CreatePalette( pPal );
451
pPal->palNumEntries = pwdc->nColors;
452
for (i = 0; i < pwdc->nColors; i++) {
453
pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
454
pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
455
pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
456
pPal->palPalEntry[i].peFlags = 0;
458
pwdc->hGLPalette = CreatePalette( pPal );
465
//---------------------------------------------------------------------------
467
/* This function sets the color table of a DIB section
468
* to match that of the destination DC
470
BOOL wmSetDibColors(PWMC pwc)
472
RGBQUAD *pColTab, *pRGB;
473
PALETTEENTRY *pPal, *pPE;
478
/* Build a color table in the DIB that maps to the
479
* selected palette in the DC.
481
nColors = 1 << pwc->cColorBits;
482
pPal = (PALETTEENTRY *)malloc( nColors * sizeof(PALETTEENTRY));
483
memset( pPal, 0, nColors * sizeof(PALETTEENTRY) );
484
GetPaletteEntries( pwc->hGLPalette, 0, nColors, pPal );
485
pColTab = (RGBQUAD *)malloc( nColors * sizeof(RGBQUAD));
486
for (i = 0, pRGB = pColTab, pPE = pPal; i < nColors; i++, pRGB++, pPE++) {
487
pRGB->rgbRed = pPE->peRed;
488
pRGB->rgbGreen = pPE->peGreen;
489
pRGB->rgbBlue = pPE->peBlue;
492
bRet = SetDIBColorTable(pwc->dib.hDC, 0, nColors, pColTab );
495
dwErr = GetLastError();
503
//---------------------------------------------------------------------------
505
static void wmSetPixelFormat( PWMC wc, HDC hDC)
508
wc->cColorBits = GetDeviceCaps(hDC, BITSPIXEL);
511
switch(wc->cColorBits){
513
if(wc->dither_flag != GL_TRUE)
514
wc->pixelformat = PF_INDEX8;
516
wc->pixelformat = PF_DITHER8;
519
wc->pixelformat = PF_5R6G5B;
522
wc->pixelformat = PF_8R8G8B;
525
wc->pixelformat = PF_BADFORMAT;
529
//---------------------------------------------------------------------------
532
* This function creates the DIB section that is used for combined
535
BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize)
538
LPBITMAPINFO pbmi = &(pwc->bmi);
541
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
542
pbmi->bmiHeader.biWidth = lxSize;
543
pbmi->bmiHeader.biHeight= -lySize;
544
pbmi->bmiHeader.biPlanes = 1;
546
pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwc->hDC, BITSPIXEL);
548
pbmi->bmiHeader.biBitCount = 8;
549
pbmi->bmiHeader.biCompression = BI_RGB;
550
pbmi->bmiHeader.biSizeImage = 0;
551
pbmi->bmiHeader.biXPelsPerMeter = 0;
552
pbmi->bmiHeader.biYPelsPerMeter = 0;
553
pbmi->bmiHeader.biClrUsed = 0;
554
pbmi->bmiHeader.biClrImportant = 0;
556
iUsage = (pbmi->bmiHeader.biBitCount <= 8) ? DIB_PAL_COLORS : DIB_RGB_COLORS;
558
pwc->cColorBits = pbmi->bmiHeader.biBitCount;
559
pwc->ScanWidth = pwc->pitch = lxSize;
561
pwc->height = lySize;
563
wmCreateDIBSection(hdc, pwc, pbmi, iUsage);
565
if ((iUsage == DIB_PAL_COLORS) && !(pwc->hGLPalette)) {
566
wmCreatePalette( pwc );
567
wmSetDibColors( pwc );
569
wmSetPixelFormat(pwc, pwc->hDC);
573
//---------------------------------------------------------------------------
576
* Free up the dib section that was created
578
BOOL wmDeleteBackingStore(PWMC pwc)
580
SelectObject(pwc->dib.hDC, pwc->hOldBitmap);
581
DeleteDC(pwc->dib.hDC);
582
DeleteObject(pwc->hbmDIB);
583
UnmapViewOfFile(pwc->dib.base);
584
CloseHandle(pwc->dib.hFileMap);
588
//---------------------------------------------------------------------------
591
* Blit memory DC to screen DC
593
BOOL wmFlush(PWMC pwc, HDC hDC)
598
// Now using bEmulateSingleBuffer in the calling function. KeithH
601
bRet = BitBlt(hDC, 0, 0, pwc->width, pwc->height,
602
pwc->dib.hDC, 0, 0, SRCCOPY);
609
//---------------------------------------------------------------------------
611
//---------------------------------------------------------------------------
613
static void flush(GLcontext* ctx)
615
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
616
WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
618
if((Current->rgb_flag &&!(Current->db_flag))
619
||(!Current->rgb_flag))
621
wmFlush(Current, Current->hDC);
624
// Only flush if we're not in double-buffer mode. KeithH
625
// The demo fractal.c calls glutSwapBuffers() then glFlush()!
626
if (Current->bEmulateSingleBuffer) {
627
wmFlush(Current, Current->hDC);
632
//---------------------------------------------------------------------------
636
* Set the color index used to clear the color buffer.
638
static void clear_index(GLcontext* ctx, GLuint index)
640
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
641
WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
642
Current->clearpixel = index;
647
//---------------------------------------------------------------------------
650
* Set the color used to clear the color buffer.
652
//static void clear_color( GLcontext* ctx, const GLchan color[4] )
653
// Changed for Mesa 5.x. KeithH
654
static void clear_color(
656
const GLfloat color[4])
658
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
659
WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
661
CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]);
662
CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]);
663
CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]);
664
Current->clearpixel = RGB(col[0], col[1], col[2]);
668
//---------------------------------------------------------------------------
672
* Clear the specified region of the color buffer using the clear color
673
* or index as specified by one of the two functions above.
675
* This procedure clears either the front and/or the back COLOR buffers.
676
* Only the "left" buffer is cleared since we are not stereo.
677
* Clearing of the other non-color buffers is left to the swrast.
678
* We also only clear the color buffers if the color masks are all 1's.
679
* Otherwise, we let swrast do it.
682
static clear(GLcontext* ctx, GLbitfield mask,
683
GLboolean all, GLint x, GLint y, GLint width, GLint height)
685
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
686
WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
690
LPDWORD lpdw = (LPDWORD)Current->pbPixels;
691
LPWORD lpw = (LPWORD)Current->pbPixels;
692
LPBYTE lpb = Current->pbPixels;
694
const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask;
698
width=Current->width;
699
height=Current->height;
703
/* sanity check - can't have right(stereo) buffers */
704
assert((mask & (DD_FRONT_RIGHT_BIT | DD_BACK_RIGHT_BIT)) == 0);
707
if ((mask & (DD_FRONT_LEFT_BIT | DD_BACK_RIGHT_BIT)) &&
708
ctx->DrawBuffer->UseSoftwareAlphaBuffers &&
709
ctx->Color.ColorMask[ACOMP]) {
710
_swrast_clear_alpha_buffers( ctx );
713
if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) {
714
if (mask & DD_BACK_LEFT_BIT) {
715
/* Double-buffering - clear back buffer */
716
UINT nBypp = Current->cColorBits / 8;
720
assert(Current->db_flag==GL_TRUE); /* we'd better be double buffer */
722
iSize = Current->width/4;
723
bColor = BGR8(GetRValue(Current->clearpixel),
724
GetGValue(Current->clearpixel),
725
GetBValue(Current->clearpixel));
726
wColor = MAKEWORD(bColor,bColor);
727
dwColor = MAKELONG(wColor, wColor);
730
iSize = Current->width / 2;
731
wColor = BGR16(GetRValue(Current->clearpixel),
732
GetGValue(Current->clearpixel),
733
GetBValue(Current->clearpixel));
734
dwColor = MAKELONG(wColor, wColor);
737
iSize = Current->width;
738
dwColor = BGR32(GetRValue(Current->clearpixel),
739
GetGValue(Current->clearpixel),
740
GetBValue(Current->clearpixel));
750
/* This is the 24bit case */
752
iSize = Current->width *3/4;
753
dwColor = BGR24(GetRValue(Current->clearpixel),
754
GetGValue(Current->clearpixel),
755
GetBValue(Current->clearpixel));
769
/* copy cleared line to other lines in buffer */
771
memcpy(lpb, Current->pbPixels, iSize*4);
772
lpb += Current->ScanWidth;
776
mask &= ~DD_BACK_LEFT_BIT;
777
} /* double-buffer */
779
if (mask & DD_FRONT_LEFT_BIT) {
782
HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel);
783
HBRUSH Brush=CreateSolidBrush(Current->clearpixel);
784
HPEN Old_Pen=SelectObject(DC,Pen);
785
HBRUSH Old_Brush=SelectObject(DC,Brush);
786
Rectangle(DC,x,y,x+width,y+height);
787
SelectObject(DC,Old_Pen);
788
SelectObject(DC,Old_Brush);
792
mask &= ~DD_FRONT_LEFT_BIT;
793
} /* single-buffer */
794
} /* if masks are all 1's */
796
/* Call swrast if there is anything left to clear (like DEPTH) */
798
_swrast_Clear( ctx, mask, all, x, y, width, height );
802
//---------------------------------------------------------------------------
805
static void enable( GLcontext* ctx, GLenum pname, GLboolean enable )
807
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
808
WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
813
if (pname == GL_DITHER) {
814
if(enable == GL_FALSE){
815
Current->dither_flag = GL_FALSE;
816
if(Current->cColorBits == 8)
817
Current->pixelformat = PF_INDEX8;
820
if (Current->rgb_flag && Current->cColorBits == 8){
821
Current->pixelformat = PF_DITHER8;
822
Current->dither_flag = GL_TRUE;
825
Current->dither_flag = GL_FALSE;
830
//---------------------------------------------------------------------------
832
static GLboolean set_draw_buffer( GLcontext* ctx, GLenum mode )
834
/* TODO: this could be better */
835
if (mode==GL_FRONT_LEFT || mode==GL_BACK_LEFT) {
843
//---------------------------------------------------------------------------
846
static void set_read_buffer(GLcontext *ctx, GLframebuffer *colorBuffer,
854
//---------------------------------------------------------------------------
857
/* Return characteristics of the output buffer. */
858
//static void buffer_size( GLcontext* ctx, GLuint *width, GLuint *height )
859
// Altered for Mesa 5.x. KeithH
860
static void buffer_size(
861
GLframebuffer *buffer,
865
// For some reason the context is not passed into this function.
866
// Therefore we have to explicitly retrieve it.
867
GET_CURRENT_CONTEXT(ctx);
869
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
870
WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
874
GetClientRect(Current->Window,&CR);
879
New_Size=((*width)!=Current->width) || ((*height)!=Current->height);
882
Current->width=*width;
883
Current->height=*height;
884
Current->ScanWidth=Current->width;
885
if ((Current->ScanWidth%sizeof(long))!=0)
886
Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long)));
888
if (Current->db_flag){
889
if (Current->rgb_flag==GL_TRUE && Current->dither_flag!=GL_TRUE){
890
wmDeleteBackingStore(Current);
891
wmCreateBackingStore(Current, Current->width, Current->height);
900
/**********************************************************************/
901
/***** Accelerated point, line, polygon rendering *****/
902
/**********************************************************************/
904
/* Accelerated routines are not implemented in 4.0. See OSMesa for ideas. */
906
static void fast_rgb_points( GLcontext* ctx, GLuint first, GLuint last )
910
//---------------------------------------------------------------------------
912
/* Return pointer to accelerated points function */
913
extern tnl_points_func choose_points_function( GLcontext* ctx )
918
//---------------------------------------------------------------------------
920
static void fast_flat_rgb_line( GLcontext* ctx, GLuint v0,
921
GLuint v1, GLuint pv )
925
//---------------------------------------------------------------------------
927
static tnl_line_func choose_line_function( GLcontext* ctx )
932
/**********************************************************************/
933
/***** Span-based pixel drawing *****/
934
/**********************************************************************/
937
/* Write a horizontal span of 32-bit color-index pixels with a boolean mask. */
938
static void write_ci32_span( const GLcontext* ctx,
939
GLuint n, GLint x, GLint y,
940
const GLuint index[],
941
const GLubyte mask[] )
943
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
944
WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
946
PBYTE Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
947
assert(Current->rgb_flag==GL_FALSE);
954
//---------------------------------------------------------------------------
956
/* Write a horizontal span of 8-bit color-index pixels with a boolean mask. */
957
static void write_ci8_span( const GLcontext* ctx,
958
GLuint n, GLint x, GLint y,
959
const GLubyte index[],
960
const GLubyte mask[] )
962
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
963
WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
965
PBYTE Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
966
assert(Current->rgb_flag==GL_FALSE);
973
//---------------------------------------------------------------------------
977
* Write a horizontal span of pixels with a boolean mask. The current
978
* color index is used for all pixels.
980
static void write_mono_ci_span(const GLcontext* ctx,
981
GLuint n,GLint x,GLint y,
982
GLuint colorIndex, const GLubyte mask[])
984
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
985
WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
987
BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
988
assert(Current->rgb_flag==GL_FALSE);
994
//---------------------------------------------------------------------------
997
* To improve the performance of this routine, frob the data into an actual
998
* scanline and call bitblt on the complete scan line instead of SetPixel.
1001
/* Write a horizontal span of RGBA color pixels with a boolean mask. */
1002
static void write_rgba_span( const GLcontext* ctx, GLuint n, GLint x, GLint y,
1003
const GLubyte rgba[][4], const GLubyte mask[] )
1005
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1006
WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
1009
if (pwc->rgb_flag==GL_TRUE)
1017
wmSetPixel(pwc, y, x + i,
1018
rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1022
wmSetPixel(pwc, y, x + i,
1023
rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
1030
BYTE *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
1035
Mem[i] = GetNearestPaletteIndex(Current->hPal,
1042
Mem[i] = GetNearestPaletteIndex(Current->hPal,
1050
//---------------------------------------------------------------------------
1052
/* Write a horizontal span of RGB color pixels with a boolean mask. */
1053
static void write_rgb_span( const GLcontext* ctx,
1054
GLuint n, GLint x, GLint y,
1055
const GLubyte rgb[][3], const GLubyte mask[] )
1057
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1058
WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
1061
if (pwc->rgb_flag==GL_TRUE)
1069
wmSetPixel(pwc, y, x + i,
1070
rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1074
wmSetPixel(pwc, y, x + i,
1075
rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
1082
BYTE *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
1087
Mem[i] = GetNearestPaletteIndex(Current->hPal,
1094
Mem[i] = GetNearestPaletteIndex(Current->hPal,
1102
//---------------------------------------------------------------------------
1105
* Write a horizontal span of pixels with a boolean mask. The current color
1106
* is used for all pixels.
1108
static void write_mono_rgba_span( const GLcontext* ctx,
1109
GLuint n, GLint x, GLint y,
1110
const GLchan color[4], const GLubyte mask[])
1112
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1113
WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
1114
ULONG pixel = RGB( color[RCOMP], color[GCOMP], color[BCOMP] );
1118
assert(Current->rgb_flag==GL_TRUE);
1120
if(Current->rgb_flag==GL_TRUE){
1123
wmSetPixel(pwc,y,x+i,color[RCOMP], color[GCOMP], color[BCOMP]);
1128
SetPixel(DC, y, x+i, pixel);
1135
/**********************************************************************/
1136
/***** Array-based pixel drawing *****/
1137
/**********************************************************************/
1140
/* Write an array of 32-bit index pixels with a boolean mask. */
1141
static void write_ci32_pixels( const GLcontext* ctx,
1142
GLuint n, const GLint x[], const GLint y[],
1143
const GLuint index[], const GLubyte mask[] )
1145
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1146
WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
1148
assert(Current->rgb_flag==GL_FALSE);
1149
for (i=0; i<n; i++) {
1151
BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i];
1158
//---------------------------------------------------------------------------
1162
* Write an array of pixels with a boolean mask. The current color
1163
* index is used for all pixels.
1165
static void write_mono_ci_pixels( const GLcontext* ctx,
1167
const GLint x[], const GLint y[],
1168
GLuint colorIndex, const GLubyte mask[] )
1170
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1171
WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
1173
assert(Current->rgb_flag==GL_FALSE);
1174
for (i=0; i<n; i++) {
1176
BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i];
1183
//---------------------------------------------------------------------------
1186
/* Write an array of RGBA pixels with a boolean mask. */
1187
static void write_rgba_pixels( const GLcontext* ctx,
1188
GLuint n, const GLint x[], const GLint y[],
1189
const GLubyte rgba[][4], const GLubyte mask[] )
1191
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1192
WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
1196
assert(Current->rgb_flag==GL_TRUE);
1199
wmSetPixel(pwc, FLIP(y[i]), x[i],
1200
rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1205
//---------------------------------------------------------------------------
1209
* Write an array of pixels with a boolean mask. The current color
1210
* is used for all pixels.
1212
static void write_mono_rgba_pixels( const GLcontext* ctx,
1214
const GLint x[], const GLint y[],
1215
const GLchan color[4],
1216
const GLubyte mask[] )
1218
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1219
WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
1223
assert(Current->rgb_flag==GL_TRUE);
1226
wmSetPixel(pwc, FLIP(y[i]),x[i],color[RCOMP],
1227
color[GCOMP], color[BCOMP]);
1231
/**********************************************************************/
1232
/***** Read spans/arrays of pixels *****/
1233
/**********************************************************************/
1235
/* Read a horizontal span of color-index pixels. */
1236
static void read_ci32_span( const GLcontext* ctx, GLuint n, GLint x, GLint y,
1239
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1240
WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
1242
BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
1243
assert(Current->rgb_flag==GL_FALSE);
1248
//---------------------------------------------------------------------------
1250
/* Read an array of color index pixels. */
1251
static void read_ci32_pixels( const GLcontext* ctx,
1252
GLuint n, const GLint x[], const GLint y[],
1253
GLuint indx[], const GLubyte mask[] )
1255
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1256
WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
1258
assert(Current->rgb_flag==GL_FALSE);
1259
for (i=0; i<n; i++) {
1261
indx[i]=*(Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i]);
1266
//---------------------------------------------------------------------------
1268
/* Read a horizontal span of color pixels. */
1269
static void read_rgba_span( const GLcontext* ctx,
1270
GLuint n, GLint x, GLint y,
1273
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1274
WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
1278
assert(Current->rgb_flag==GL_TRUE);
1279
y = Current->height - y - 1;
1280
for (i=0; i<n; i++) {
1281
Color=GetPixel(DC,x+i,y);
1282
rgba[i][RCOMP] = GetRValue(Color);
1283
rgba[i][GCOMP] = GetGValue(Color);
1284
rgba[i][BCOMP] = GetBValue(Color);
1285
rgba[i][ACOMP] = 255;
1290
//---------------------------------------------------------------------------
1292
/* Read an array of color pixels. */
1293
static void read_rgba_pixels( const GLcontext* ctx,
1294
GLuint n, const GLint x[], const GLint y[],
1295
GLubyte rgba[][4], const GLubyte mask[] )
1297
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1298
WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
1302
assert(Current->rgb_flag==GL_TRUE);
1303
for (i=0; i<n; i++) {
1305
GLint y2 = Current->height - y[i] - 1;
1306
Color=GetPixel(DC,x[i],y2);
1307
rgba[i][RCOMP] = GetRValue(Color);
1308
rgba[i][GCOMP] = GetGValue(Color);
1309
rgba[i][BCOMP] = GetBValue(Color);
1310
rgba[i][ACOMP] = 255;
1316
//---------------------------------------------------------------------------
1318
static void wmesa_update_state(
1322
_swrast_InvalidateState( ctx, new_state );
1323
_swsetup_InvalidateState( ctx, new_state );
1324
_ac_InvalidateState( ctx, new_state );
1325
_tnl_InvalidateState( ctx, new_state );
1328
//---------------------------------------------------------------------------
1330
static void wmesa_viewport(
1337
// ctx->Driver.ResizeBuffersMESA(ctx);
1340
//---------------------------------------------------------------------------
1342
static void wmesa_update_state_first_time(
1346
struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx );
1347
TNLcontext *tnl = TNL_CONTEXT(ctx);
1350
* XXX these function pointers could be initialized just once during
1351
* context creation since they don't depend on any state changes.
1352
* kws - This is true - this function gets called a lot and it
1353
* would be good to minimize setting all this when not needed.
1355
// Good idea, so I'll do it. KeithH. :-)
1357
ctx->Driver.GetString = _gldGetStringGeneric;
1358
ctx->Driver.UpdateState = wmesa_update_state;
1359
ctx->Driver.DrawBuffer = set_draw_buffer;
1360
ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
1361
ctx->Driver.GetBufferSize = buffer_size;
1363
ctx->Driver.Viewport = wmesa_viewport;
1365
ctx->Driver.Accum = _swrast_Accum;
1366
ctx->Driver.Bitmap = _swrast_Bitmap;
1367
ctx->Driver.Clear = clear;
1369
ctx->Driver.Flush = flush;
1370
ctx->Driver.ClearIndex = clear_index;
1371
ctx->Driver.ClearColor = clear_color;
1372
ctx->Driver.Enable = enable;
1374
ctx->Driver.CopyPixels = _swrast_CopyPixels;
1375
ctx->Driver.DrawPixels = _swrast_DrawPixels;
1376
ctx->Driver.ReadPixels = _swrast_ReadPixels;
1378
ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
1379
ctx->Driver.TexImage1D = _mesa_store_teximage1d;
1380
ctx->Driver.TexImage2D = _mesa_store_teximage2d;
1381
ctx->Driver.TexImage3D = _mesa_store_teximage3d;
1382
ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
1383
ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
1384
ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
1385
ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
1387
ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
1388
ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
1389
ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
1390
ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
1391
ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
1392
ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
1393
ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
1394
ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
1395
ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
1397
// Does not apply for Mesa 5.x
1398
//ctx->Driver.BaseCompressedTexFormat = _mesa_base_compressed_texformat;
1399
//ctx->Driver.CompressedTextureSize = _mesa_compressed_texture_size;
1400
//ctx->Driver.GetCompressedTexImage = _mesa_get_compressed_teximage;
1402
swdd->SetBuffer = set_read_buffer;
1405
/* Pixel/span writing functions: */
1406
swdd->WriteRGBASpan = write_rgba_span;
1407
swdd->WriteRGBSpan = write_rgb_span;
1408
swdd->WriteMonoRGBASpan = write_mono_rgba_span;
1409
swdd->WriteRGBAPixels = write_rgba_pixels;
1410
swdd->WriteMonoRGBAPixels = write_mono_rgba_pixels;
1411
swdd->WriteCI32Span = write_ci32_span;
1412
swdd->WriteCI8Span = write_ci8_span;
1413
swdd->WriteMonoCISpan = write_mono_ci_span;
1414
swdd->WriteCI32Pixels = write_ci32_pixels;
1415
swdd->WriteMonoCIPixels = write_mono_ci_pixels;
1417
swdd->ReadCI32Span = read_ci32_span;
1418
swdd->ReadRGBASpan = read_rgba_span;
1419
swdd->ReadCI32Pixels = read_ci32_pixels;
1420
swdd->ReadRGBAPixels = read_rgba_pixels;
1423
tnl->Driver.RunPipeline = _tnl_run_pipeline;
1425
wmesa_update_state(ctx, new_state);
1428
//---------------------------------------------------------------------------
1429
// Driver interface functions
1430
//---------------------------------------------------------------------------
1432
BOOL gldCreateDrawable_MesaSW(
1434
BOOL bPersistantInterface,
1435
BOOL bPersistantBuffers)
1438
GLboolean true_color_flag;
1439
GLboolean rgb_flag = GL_TRUE;
1440
GLboolean db_flag = GL_TRUE;
1445
c = (struct wmesa_context * ) calloc(1,sizeof(struct wmesa_context));
1452
c->Window = pCtx->hWnd;
1454
true_color_flag = GetDeviceCaps(pCtx->hDC, BITSPIXEL) > 8;
1458
if ((true_color_flag==GL_FALSE) && (rgb_flag == GL_TRUE)){
1459
c->dither_flag = GL_TRUE;
1460
c->hPalHalfTone = WinGCreateHalftonePalette();
1463
c->dither_flag = GL_FALSE;
1465
c->dither_flag = GL_FALSE;
1469
if (rgb_flag==GL_FALSE)
1471
c->rgb_flag = GL_FALSE;
1473
/* Old WinG stuff???? */
1474
c->db_flag = db_flag =GL_TRUE; /* WinG requires double buffering */
1475
printf("Single buffer is not supported in color index mode, ",
1476
"setting to double buffer.\n");
1481
c->rgb_flag = GL_TRUE;
1484
// db_flag = pCtx->lpPF->pfd.dwFlags & PFD_DOUBLEBUFFER ? GL_TRUE : GL_FALSE;
1485
db_flag = GL_TRUE; // Force double-buffer
1488
/* Double buffered */
1490
wmCreateBackingStore(c, pCtx->dwWidth, pCtx->dwHeight);
1494
/* Single Buffered */
1499
c->bEmulateSingleBuffer = (pCtx->lpPF->pfd.dwFlags & PFD_DOUBLEBUFFER)
1505
//---------------------------------------------------------------------------
1507
BOOL gldResizeDrawable_MesaSW(
1509
BOOL bDefaultDriver,
1510
BOOL bPersistantInterface,
1511
BOOL bPersistantBuffers)
1523
c->Window = ctx->hWnd;
1524
// c->width = ctx->dwWidth;
1525
// c->height = ctx->dwHeight;
1528
wmDeleteBackingStore(c);
1529
wmCreateBackingStore(c, ctx->dwWidth, ctx->dwHeight);
1535
//---------------------------------------------------------------------------
1537
BOOL gldDestroyDrawable_MesaSW(
1549
if (c->hPalHalfTone != NULL)
1550
DeleteObject(c->hPalHalfTone);
1553
wmDeleteBackingStore(c);
1562
//---------------------------------------------------------------------------
1564
BOOL gldCreatePrivateGlobals_MesaSW(void)
1566
// Mesa Software driver needs no private globals
1570
//---------------------------------------------------------------------------
1572
BOOL gldDestroyPrivateGlobals_MesaSW(void)
1574
// Mesa Software driver needs no private globals
1578
//---------------------------------------------------------------------------
1580
BOOL gldBuildPixelformatList_MesaSW(void)
1582
// Release any existing pixelformat list
1587
glb.nPixelFormatCount = 0;
1590
glb.lpPF = (DGL_pixelFormat *)calloc(2, sizeof(DGL_pixelFormat));
1591
if (glb.lpPF == NULL)
1594
memcpy(&glb.lpPF[0], &pfTemplateMesaSW, sizeof(DGL_pixelFormat));
1595
glb.lpPF[0].pfd.dwFlags &= ~PFD_DOUBLEBUFFER; // Remove doublebuffer flag
1597
memcpy(&glb.lpPF[1], &pfTemplateMesaSW, sizeof(DGL_pixelFormat));
1598
glb.nPixelFormatCount = 2;
1600
// Mark list as 'current'
1601
glb.bPixelformatsDirty = FALSE;
1606
//---------------------------------------------------------------------------
1608
BOOL gldInitialiseMesa_MesaSW(
1618
// Set max texture size to 256
1619
ctx->Const.MaxTextureLevels = 8;
1621
// Multitexture enable/disable
1622
ctx->Const.MaxTextureUnits = (glb.bMultitexture) ? MAX_TEXTURE_UNITS : 1;
1624
/* Initialize the software rasterizer and helper modules.*/
1626
// Added this to force max texture diminsion to 256. KeithH
1627
ctx->Const.MaxTextureLevels = 8;
1629
_mesa_enable_sw_extensions(ctx);
1630
_mesa_enable_imaging_extensions(ctx);
1631
_mesa_enable_1_3_extensions(ctx);
1633
// _swrast_CreateContext( ctx );
1634
// _ac_CreateContext( ctx );
1635
// _tnl_CreateContext( ctx );
1636
// _swsetup_CreateContext( ctx );
1638
_swsetup_Wakeup( ctx );
1640
wmesa_update_state_first_time(ctx, ~0);
1645
//---------------------------------------------------------------------------
1647
BOOL gldSwapBuffers_MesaSW(
1661
/* If we're swapping the buffer associated with the current context
1662
* we have to flush any pending rendering commands first.
1665
// Altered to respect bEmulateSingleBuffer. KeithH
1667
if (!c->bEmulateSingleBuffer)
1673
//---------------------------------------------------------------------------
1675
PROC gldGetProcAddress_MesaSW(
1681
for (i=0; GLD_extList[i].proc; i++) {
1682
if (!strcmp(a, GLD_extList[i].name)) {
1683
proc = GLD_extList[i].proc;
1688
gldLogPrintf(GLDLOG_INFO, "GetProcAddress: %s (%s)", a, proc ? "OK" : "Failed");
1693
//---------------------------------------------------------------------------
1695
BOOL gldGetDisplayMode_MesaSW(
1697
GLD_displayMode *glddm)
1705
// A bit hacky... KeithH
1708
hdcDesktop = GetDC(NULL);
1709
glddm->Width = GetDeviceCaps(hdcDesktop, HORZRES);
1710
glddm->Height = GetDeviceCaps(hdcDesktop, VERTRES);
1711
glddm->BPP = GetDeviceCaps(hdcDesktop, BITSPIXEL);
1713
ReleaseDC(0, hdcDesktop);
1718
//---------------------------------------------------------------------------