patch by blight:

Simple GL programs should work if you have hardware-accelerated video drivers installed, still some bugs left and things to implement; Have already played a model-flight simulator with it.

svn path=/trunk/; revision=8162
This commit is contained in:
Royce Mitchell III
2004-02-12 23:56:15 +00:00
parent ca9c59183f
commit b68208f089
3 changed files with 102 additions and 61 deletions
+22 -15
View File
@@ -1,4 +1,4 @@
/* $Id: opengl32.c,v 1.14 2004/02/09 08:00:15 vizzini Exp $
/* $Id: opengl32.c,v 1.15 2004/02/12 23:56:15 royce Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -34,13 +34,6 @@ static DWORD OPENGL32_InitializeDriver( GLDRIVERDATA *icd );
static BOOL OPENGL32_UnloadDriver( GLDRIVERDATA *icd );
/* global vars */
/*const char* OPENGL32_funcnames[GLIDX_COUNT] SHARED =
{
#define X(func, ret, typeargs, args) #func,
GLFUNCS_MACRO
#undef X
};*/
DWORD OPENGL32_tls;
GLPROCESSDATA OPENGL32_processdata;
@@ -51,6 +44,8 @@ OPENGL32_ThreadDetach()
{
/* FIXME - do we need to release some HDC or something? */
GLTHREADDATA* lpData = NULL;
PROC *dispatchTable = NULL;
lpData = (GLTHREADDATA*)TlsGetValue( OPENGL32_tls );
if (lpData != NULL)
{
@@ -58,6 +53,16 @@ OPENGL32_ThreadDetach()
DBGPRINT( "Warning: HeapFree() on GLTHREADDATA failed (%d)",
GetLastError() );
}
dispatchTable = NtCurrentTeb()->glTable;
if (dispatchTable != NULL)
{
if (!HeapFree( GetProcessHeap(), 0, dispatchTable ))
DBGPRINT( "Warning: HeapFree() on dispatch table failed (%d)",
GetLastError() );
}
}
@@ -66,7 +71,7 @@ WINAPI
DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
{
GLTHREADDATA* lpData = NULL;
ICDTable *dispatchTable = NULL;
PROC *dispatchTable = NULL;
TEB *teb = NULL;
SECURITY_ATTRIBUTES attrib = { sizeof (SECURITY_ATTRIBUTES), /* nLength */
NULL, /* lpSecurityDescriptor */
@@ -106,9 +111,9 @@ DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
/* The attached process creates a new thread. */
case DLL_THREAD_ATTACH:
dispatchTable = (ICDTable*)HeapAlloc( GetProcessHeap(),
dispatchTable = (PROC*)HeapAlloc( GetProcessHeap(),
HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY,
sizeof (ICDTable) );
sizeof (((ICDTable *)(0))->dispatch_table) );
if (dispatchTable == NULL)
{
DBGPRINT( "Error: Couldn't allocate GL dispatch table" );
@@ -129,13 +134,13 @@ DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
/* initialize dispatch table with empty functions */
#define X(func, ret, typeargs, args, icdidx, tebidx, stack) \
dispatchTable->dispatch_table[icdidx] = (PROC)glEmptyFunc##stack; \
dispatchTable[icdidx] = (PROC)glEmptyFunc##stack; \
if (tebidx >= 0) \
teb->glDispatchTable[tebidx] = (PVOID)glEmptyFunc##stack;
GLFUNCS_MACRO
#undef X
teb->glTable = dispatchTable->dispatch_table;
teb->glTable = dispatchTable;
TlsSetValue( OPENGL32_tls, lpData );
break;
@@ -332,7 +337,7 @@ OPENGL32_InitializeDriver( GLDRIVERDATA *icd )
LOAD_DRV_PROC(icd, DrvSwapLayerBuffers, TRUE);
/* we require at least one of DrvCreateContext and DrvCreateLayerContext */
if (icd->DrvCreateContext == NULL || icd->DrvCreateLayerContext == NULL)
if (icd->DrvCreateContext == NULL && icd->DrvCreateLayerContext == NULL)
{
DBGPRINT( "Error: One of DrvCreateContext/DrvCreateLayerContext is required!" );
FreeLibrary( icd->handle );
@@ -464,8 +469,10 @@ OPENGL32_UnloadICD( GLDRIVERDATA *icd )
}
icd->refcount--;
if (icd->refcount == 0)
//if (icd->refcount == 0)
if (0)
ret = OPENGL32_UnloadDriver( icd );
/* FIXME: InitializeICD crashes when called a second time */
/* release mutex */
if (!ReleaseMutex( OPENGL32_processdata.driver_mutex ))
+2 -2
View File
@@ -1,4 +1,4 @@
/* $Id: opengl32.h,v 1.13 2004/02/11 17:39:24 vizzini Exp $
/* $Id: opengl32.h,v 1.14 2004/02/12 23:56:15 royce Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -115,7 +115,7 @@ typedef struct tagGLDRIVERDATA
BOOL APIENTRY (*DrvDescribeLayerPlane)( HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR );
int APIENTRY (*DrvDescribePixelFormat)( IN HDC, IN int, IN UINT, OUT LPPIXELFORMATDESCRIPTOR );
int APIENTRY (*DrvGetLayerPaletteEntries)( HDC, int, int, int, COLORREF * );
FARPROC APIENTRY (*DrvGetProcAddress)( LPCSTR lpProcName );
PROC APIENTRY (*DrvGetProcAddress)( LPCSTR lpProcName );
void APIENTRY (*DrvReleaseContext)();
BOOL APIENTRY (*DrvRealizeLayerPalette)( HDC, int, BOOL );
PICDTable APIENTRY (*DrvSetContext)( HDC hdc, HGLRC hglrc, SetContextCallBack callback );
+78 -44
View File
@@ -127,7 +127,7 @@ WGL_ContainsContext( GLRC *glrc )
* be multiple times for one DrvSetContext call.
* ARGUMENTS: [IN] table Function pointer table (first DWORD is number of
* functions)
* RETURNS: unkown
* RETURNS: unkown (maybe void?)
*/
DWORD
CALLBACK
@@ -136,18 +136,27 @@ WGL_SetContextCallBack( const ICDTable *table )
/* UINT i;*/
TEB *teb;
PROC *tebTable, *tebDispatchTable;
INT size;
teb = NtCurrentTeb();
tebTable = (PROC *)teb->glTable;
tebDispatchTable = (PROC *)teb->glDispatchTable;
DBGPRINT( "Function count: %d\n", table->num_funcs );
if (table != NULL)
{
DBGPRINT( "Function count: %d\n", table->num_funcs );
/* save table */
memcpy( tebTable, table->dispatch_table,
sizeof (PROC) * table->num_funcs );
memset( tebTable + sizeof (PROC) * table->num_funcs, 0,
sizeof (table->dispatch_table) - (sizeof (PROC) * table->num_funcs) );
/* save table */
size = sizeof (PROC) * table->num_funcs;
memcpy( tebTable, table->dispatch_table, size );
memset( tebTable + table->num_funcs, 0,
sizeof (table->dispatch_table) - size );
}
else
{
DBGPRINT( "Unsetting current context" );
memset( tebTable, 0, sizeof (table->dispatch_table) );
}
/* FIXME: pull in software fallbacks -- need mesa */
#if 0 /* unused atm */
@@ -165,7 +174,8 @@ WGL_SetContextCallBack( const ICDTable *table )
#define X(func, ret, typeargs, args, icdidx, tebidx, stack) \
if (tebTable[icdidx] == NULL) \
{ \
DBGPRINT( "Warning: GL proc '%s' is NULL", #func ); \
if (table != NULL) \
DBGPRINT( "Warning: GL proc '%s' is NULL", #func ); \
tebTable[icdidx] = (PROC)glEmptyFunc##stack; \
}
GLFUNCS_MACRO
@@ -209,6 +219,7 @@ rosglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *pfd )
/* check input */
if (pfd->nSize != sizeof (PIXELFORMATDESCRIPTOR) || pfd->nVersion != 1)
{
OPENGL32_UnloadICD( icd );
SetLastError( 0 ); /* FIXME: use appropriate errorcode */
return 0;
}
@@ -219,6 +230,7 @@ rosglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *pfd )
if (icdNumFormats == 0)
{
DBGPRINT( "Error: DrvDescribePixelFormat failed (%d)", GetLastError() );
OPENGL32_UnloadICD( icd );
return 0;
}
DBGPRINT( "Info: Enumerating %d pixelformats", icdNumFormats );
@@ -269,6 +281,7 @@ rosglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *pfd )
if (best == 0)
SetLastError( 0 ); /* FIXME: set appropriate error */
OPENGL32_UnloadICD( icd );
DBGPRINT( "Info: Suggesting pixelformat %d", best );
return best;
@@ -503,6 +516,7 @@ rosglDescribePixelFormat( HDC hdc, int iFormat, UINT nBytes,
ret = icd->DrvDescribePixelFormat( hdc, iFormat, nBytes, pfd );
if (ret == 0)
DBGPRINT( "Error: DrvDescribePixelFormat(format=%d) failed (%d)", iFormat, GetLastError() );
OPENGL32_UnloadICD( icd );
}
/* FIXME: implement own functionality? */
@@ -576,7 +590,9 @@ rosglGetProcAddress( LPCSTR proc )
if (proc[0] == 'g' && proc[1] == 'l') /* glXXX */
{
PROC glXXX = OPENGL32_threaddata->glrc->icd->DrvGetProcAddress( proc );
PROC glXXX = NULL;
GLDRIVERDATA *icd = OPENGL32_threaddata->glrc->icd;
glXXX = icd->DrvGetProcAddress( proc );
if (glXXX)
{
DBGPRINT( "Info: Proc \"%s\" loaded from ICD.", proc );
@@ -619,47 +635,61 @@ rosglMakeCurrent( HDC hdc, HGLRC hglrc )
glFlush();
}
/* check hdc */
if (GetObjectType( hdc ) != OBJ_DC)
/* check if current context is unset */
if (glrc == NULL)
{
DBGPRINT( "Error: hdc is not a DC handle!" );
return FALSE;
}
/* check if we know about this glrc */
if (!WGL_ContainsContext( glrc ))
{
DBGPRINT( "Error: hglrc not found!" );
return FALSE; /* FIXME: SetLastError() */
}
/* check if it is available */
if (glrc->is_current) /* used by another thread */
{
DBGPRINT( "Error: hglrc is current for thread 0x%08x", glrc->thread_id );
return FALSE; /* FIXME: SetLastError() */
}
/* call the ICD */
if (glrc->hglrc != NULL)
{
icdTable = glrc->icd->DrvSetContext( hdc, glrc->hglrc,
WGL_SetContextCallBack );
if (icdTable == NULL)
if (OPENGL32_threaddata->glrc != NULL)
{
DBGPRINT( "Error: DrvSetContext failed (%d)\n", GetLastError() );
OPENGL32_threaddata->glrc->is_current = FALSE;
OPENGL32_threaddata->glrc = NULL;
}
}
else
{
/* check hdc */
if (GetObjectType( hdc ) != OBJ_DC && GetObjectType( hdc ) != OBJ_MEMDC)
{
DBGPRINT( "Error: hdc is not a DC handle!" );
return FALSE;
}
DBGPRINT( "Info: DrvSetContext succeeded!" );
/* check if we know about this glrc */
if (!WGL_ContainsContext( glrc ))
{
DBGPRINT( "Error: hglrc not found!" );
return FALSE; /* FIXME: SetLastError() */
}
/* check if it is available */
if (glrc->is_current && glrc->thread_id != GetCurrentThreadId()) /* used by another thread */
{
DBGPRINT( "Error: hglrc is current for thread 0x%08x", glrc->thread_id );
return FALSE; /* FIXME: SetLastError() */
}
/* call the ICD */
if (glrc->hglrc != NULL)
{
icdTable = glrc->icd->DrvSetContext( hdc, glrc->hglrc,
WGL_SetContextCallBack );
if (icdTable == NULL)
{
DBGPRINT( "Error: DrvSetContext failed (%d)\n", GetLastError() );
return FALSE;
}
DBGPRINT( "Info: DrvSetContext succeeded!" );
}
/* make it current */
if (OPENGL32_threaddata->glrc != NULL)
OPENGL32_threaddata->glrc->is_current = FALSE;
glrc->is_current = TRUE;
glrc->thread_id = GetCurrentThreadId();
glrc->hdc = hdc;
OPENGL32_threaddata->glrc = glrc;
}
/* make it current */
if (OPENGL32_threaddata->glrc != NULL)
OPENGL32_threaddata->glrc->is_current = FALSE;
glrc->is_current = TRUE;
glrc->thread_id = GetCurrentThreadId();
glrc->hdc = hdc;
OPENGL32_threaddata->glrc = glrc;
WGL_SetContextCallBack( icdTable );
if (icdTable != NULL)
if (WGL_SetContextCallBack( icdTable ) != ERROR_SUCCESS)
@@ -704,11 +734,13 @@ rosglSetPixelFormat( HDC hdc, int iFormat, CONST PIXELFORMATDESCRIPTOR *pfd )
{
DBGPRINT( "Warning: DrvSetPixelFormat(format=%d) failed (%d)",
iFormat, GetLastError() );
OPENGL32_UnloadICD( icd );
return FALSE;
}
OPENGL32_processdata.cachedHdc = hdc;
OPENGL32_processdata.cachedFormat = iFormat;
OPENGL32_UnloadICD( icd );
return TRUE;
}
@@ -764,8 +796,10 @@ rosglSwapBuffers( HDC hdc )
if (!icd->DrvSwapBuffers( hdc ))
{
DBGPRINT( "Error: DrvSwapBuffers failed (%d)", GetLastError() );
OPENGL32_UnloadICD( icd );
return FALSE;
}
OPENGL32_UnloadICD( icd );
return TRUE;
}