Author: khornicek
Date: Sun Mar 19 22:15:58 2017
New Revision: 74207
URL:
http://svn.reactos.org/svn/reactos?rev=74207&view=rev
Log:
[OPENGL32]
Disclaimer: This code is ReactOS specific and is the complete opposite of what Windows
does (tm):
- Add the option to override the default OpenGL driver by a custom driver or to force the
use of the built-in software implementation.
- This will allow some more flexibility when running games / apps that depend on OGL.
- This code needs a special entry in the registry so opengl32 behaves as usual by
default.
Modified:
trunk/reactos/dll/opengl/opengl32/icdload.c
trunk/reactos/dll/opengl/opengl32/wgl.c
Modified: trunk/reactos/dll/opengl/opengl32/icdload.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/opengl/opengl32/icdloa…
==============================================================================
--- trunk/reactos/dll/opengl/opengl32/icdload.c [iso-8859-1] (original)
+++ trunk/reactos/dll/opengl/opengl32/icdload.c [iso-8859-1] Sun Mar 19 22:15:58 2017
@@ -11,16 +11,27 @@
WINE_DEFAULT_DEBUG_CHANNEL(opengl32);
-struct Drv_Opengl_Info
+typedef struct
{
DWORD Version; /*!< Driver interface version */
DWORD DriverVersion; /*!< Driver version */
WCHAR DriverName[256]; /*!< Driver name */
-};
+} Drv_Opengl_Info, *pDrv_Opengl_Info;
+
+typedef enum
+{
+ OGL_CD_NOT_QUERIED,
+ OGL_CD_NONE,
+ OGL_CD_ROSSWI,
+ OGL_CD_CUSTOM_ICD
+} CUSTOM_DRIVER_STATE;
static CRITICAL_SECTION icdload_cs = {NULL, -1, 0, 0, 0, 0};
static struct ICD_Data* ICD_Data_List = NULL;
static const WCHAR OpenGLDrivers_Key[] = L"SOFTWARE\\Microsoft\\Windows
NT\\CurrentVersion\\OpenGLDrivers";
+static const WCHAR CustomDrivers_Key[] = L"SOFTWARE\\ReactOS\\OpenGL";
+static Drv_Opengl_Info CustomDrvInfo;
+static CUSTOM_DRIVER_STATE CustomDriverState = OGL_CD_NOT_QUERIED;
static void APIENTRY wglSetCurrentValue(PVOID value)
{
@@ -47,41 +58,99 @@
{
int ret;
DWORD dwInput, dwValueType, Version, DriverVersion, Flags;
- struct Drv_Opengl_Info DrvInfo;
+ Drv_Opengl_Info DrvInfo;
+ pDrv_Opengl_Info pDrvInfo;
struct ICD_Data* data;
- HKEY OglKey, DrvKey;
+ HKEY OglKey, DrvKey, CustomKey;
WCHAR DllName[MAX_PATH];
BOOL (WINAPI *DrvValidateVersion)(DWORD);
void (WINAPI *DrvSetCallbackProcs)(int nProcs, PROC* pProcs);
-
- /* First, see if the driver supports this */
- dwInput = OPENGL_GETINFO;
- ret = ExtEscape(hdc,
- QUERYESCSUPPORT,
- sizeof(DWORD),
- (LPCSTR)&dwInput,
- 0,
- NULL);
-
- if(ret <= 0)
- {
+
+ /* The following code is ReactOS specific and allows us to easily load an arbitrary
ICD:
+ * It checks HKCU\Software\ReactOS\OpenGL for a custom ICD and will always load it
+ * no matter what driver the DC is associated with. It can also force using the
+ * built-in Software Implementation*/
+ if(CustomDriverState == OGL_CD_NOT_QUERIED)
+ {
+ /* Only do this once so there's not any significant performance penalty */
+ CustomDriverState = OGL_CD_NONE;
+ memset(&CustomDrvInfo, 0, sizeof(Drv_Opengl_Info));
+
+ ret = RegOpenKeyExW(HKEY_CURRENT_USER, CustomDrivers_Key, 0, KEY_READ,
&CustomKey);
+ if(ret != ERROR_SUCCESS)
+ goto custom_end;
+
+ dwInput = sizeof(CustomDrvInfo.DriverName);
+ ret = RegQueryValueExW(CustomKey, L"", 0, &dwValueType,
(LPBYTE)CustomDrvInfo.DriverName, &dwInput);
+ RegCloseKey(CustomKey);
+
+ if((ret != ERROR_SUCCESS) || (dwValueType != REG_SZ) ||
!wcslen(CustomDrvInfo.DriverName))
+ goto custom_end;
+
+ if(!_wcsicmp(CustomDrvInfo.DriverName, L"ReactOS Software
Implementation"))
+ {
+ /* Always announce the fact that we're forcing ROSSWI */
+ ERR("Forcing ReactOS Software Implementation\n");
+ CustomDriverState = OGL_CD_ROSSWI;
+ return NULL;
+ }
+
+ ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, OpenGLDrivers_Key, 0, KEY_READ,
&OglKey);
+ if(ret != ERROR_SUCCESS)
+ goto custom_end;
+
+ ret = RegOpenKeyExW(OglKey, CustomDrvInfo.DriverName, 0, KEY_READ, &OglKey);
+ if(ret != ERROR_SUCCESS)
+ goto custom_end;
+
+ dwInput = sizeof(CustomDrvInfo.Version);
+ ret = RegQueryValueExW(OglKey, L"Version", 0, &dwValueType,
(LPBYTE)&CustomDrvInfo.Version, &dwInput);
+ if((ret != ERROR_SUCCESS) || (dwValueType != REG_DWORD))
+ goto custom_end;
+
+ dwInput = sizeof(DriverVersion);
+ ret = RegQueryValueExW(OglKey, L"DriverVersion", 0, &dwValueType,
(LPBYTE)&CustomDrvInfo.DriverVersion, &dwInput);
+ CustomDriverState = OGL_CD_CUSTOM_ICD;
+
+ /* Always announce the fact that we're overriding the default driver */
+ ERR("Overriding the default OGL ICD with %S\n",
CustomDrvInfo.DriverName);
+
+custom_end:
+ if(OglKey)
+ RegCloseKey(OglKey);
+ RegCloseKey(CustomKey);
+ }
+
+ /* If there's a custom ICD or ROSSWI was requested use it, otherwise proceed as
usual */
+ if(CustomDriverState == OGL_CD_CUSTOM_ICD)
+ {
+ pDrvInfo = &CustomDrvInfo;
+ }
+ else if(CustomDriverState == OGL_CD_ROSSWI)
+ {
+ return NULL;
+ }
+ else
+ {
+ /* First, see if the driver supports this */
+ dwInput = OPENGL_GETINFO;
+ ret = ExtEscape(hdc, QUERYESCSUPPORT, sizeof(DWORD), (LPCSTR)&dwInput, 0,
NULL);
+
/* Driver doesn't support opengl */
- return NULL;
- }
-
- /* Query for the ICD DLL name and version */
- dwInput = 0;
- ret = ExtEscape(hdc,
- OPENGL_GETINFO,
- sizeof(DWORD),
- (LPCSTR)&dwInput,
- sizeof(DrvInfo),
- (LPSTR)&DrvInfo);
-
- if(ret <= 0)
- {
- ERR("Driver claims to support OPENGL_GETINFO escape code, but
doesn't.\n");
- return NULL;
+ if(ret <= 0)
+ return NULL;
+
+ /* Query for the ICD DLL name and version */
+ dwInput = 0;
+ ret = ExtEscape(hdc, OPENGL_GETINFO, sizeof(DWORD), (LPCSTR)&dwInput,
sizeof(DrvInfo), (LPSTR)&DrvInfo);
+
+ if(ret <= 0)
+ {
+ ERR("Driver claims to support OPENGL_GETINFO escape code, but
doesn't.\n");
+ return NULL;
+ }
+
+ pDrvInfo = &DrvInfo;
}
/* Protect the list while we are loading*/
@@ -91,7 +160,7 @@
data = ICD_Data_List;
while(data)
{
- if(!_wcsicmp(data->DriverName, DrvInfo.DriverName))
+ if(!_wcsicmp(data->DriverName, pDrvInfo->DriverName))
{
/* Found it */
TRACE("Found already loaded %p.\n", data);
@@ -108,16 +177,16 @@
ERR("Failed to open the OpenGLDrivers key.\n");
goto end;
}
- ret = RegOpenKeyExW(OglKey, DrvInfo.DriverName, 0, KEY_READ, &DrvKey);
+ ret = RegOpenKeyExW(OglKey, pDrvInfo->DriverName, 0, KEY_READ, &DrvKey);
if(ret != ERROR_SUCCESS)
{
/* Some driver installer just provide the DLL name, like the Matrox G400 */
- TRACE("No driver subkey for %S, trying to get DLL name directly.\n",
DrvInfo.DriverName);
+ TRACE("No driver subkey for %S, trying to get DLL name directly.\n",
pDrvInfo->DriverName);
dwInput = sizeof(DllName);
- ret = RegQueryValueExW(OglKey, DrvInfo.DriverName, 0, &dwValueType,
(LPBYTE)DllName, &dwInput);
+ ret = RegQueryValueExW(OglKey, pDrvInfo->DriverName, 0, &dwValueType,
(LPBYTE)DllName, &dwInput);
if((ret != ERROR_SUCCESS) || (dwValueType != REG_SZ))
{
- ERR("Unable to get ICD DLL name!.\n");
+ ERR("Unable to get ICD DLL name!\n");
RegCloseKey(OglKey);
goto end;
}
@@ -127,7 +196,7 @@
else
{
/* The driver have a subkey for the ICD */
- TRACE("Querying details from registry for %S.\n", DrvInfo.DriverName);
+ TRACE("Querying details from registry for %S.\n",
pDrvInfo->DriverName);
dwInput = sizeof(DllName);
ret = RegQueryValueExW(DrvKey, L"Dll", 0, &dwValueType,
(LPBYTE)DllName, &dwInput);
if((ret != ERROR_SUCCESS) || (dwValueType != REG_SZ))
@@ -144,9 +213,9 @@
{
WARN("No version in driver subkey\n");
}
- else if(Version != DrvInfo.Version)
- {
- ERR("Version mismatch between registry (%lu) and display driver
(%lu).\n", Version, DrvInfo.Version);
+ else if(Version != pDrvInfo->Version)
+ {
+ ERR("Version mismatch between registry (%lu) and display driver
(%lu).\n", Version, pDrvInfo->Version);
RegCloseKey(DrvKey);
RegCloseKey(OglKey);
goto end;
@@ -158,9 +227,9 @@
{
WARN("No driver version in driver subkey\n");
}
- else if(DriverVersion != DrvInfo.DriverVersion)
- {
- ERR("Driver version mismatch between registry (%lu) and display driver
(%lu).\n", DriverVersion, DrvInfo.DriverVersion);
+ else if(DriverVersion != pDrvInfo->DriverVersion)
+ {
+ ERR("Driver version mismatch between registry (%lu) and display driver
(%lu).\n", DriverVersion, pDrvInfo->DriverVersion);
RegCloseKey(DrvKey);
RegCloseKey(OglKey);
goto end;
@@ -206,7 +275,7 @@
DrvValidateVersion = (void*)GetProcAddress(data->hModule,
"DrvValidateVersion");
if(DrvValidateVersion)
{
- if(!DrvValidateVersion(DrvInfo.DriverVersion))
+ if(!DrvValidateVersion(pDrvInfo->DriverVersion))
{
ERR("DrvValidateVersion failed!.\n");
goto fail;
@@ -262,13 +331,14 @@
}
/* Copy the DriverName */
- wcscpy(data->DriverName, DrvInfo.DriverName);
+ wcscpy(data->DriverName, pDrvInfo->DriverName);
/* Push the list */
data->next = ICD_Data_List;
ICD_Data_List = data;
TRACE("Returning %p.\n", data);
+ TRACE("ICD driver %S (%S) successfully loaded.\n", pDrvInfo->DriverName,
DllName);
end:
/* Unlock and return */
Modified: trunk/reactos/dll/opengl/opengl32/wgl.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/opengl/opengl32/wgl.c?…
==============================================================================
--- trunk/reactos/dll/opengl/opengl32/wgl.c [iso-8859-1] (original)
+++ trunk/reactos/dll/opengl/opengl32/wgl.c [iso-8859-1] Sun Mar 19 22:15:58 2017
@@ -79,7 +79,7 @@
data->nb_icd_formats = data->icd_data->DrvDescribePixelFormat(hdc, 0, 0,
NULL);
else
data->nb_icd_formats = 0;
- TRACE("ICD %S has %u formats for HDC %x.\n",
data->icd_data->DriverName, data->nb_icd_formats, hdc);
+ TRACE("ICD %S has %u formats for HDC %x.\n", data->icd_data ?
data->icd_data->DriverName : NULL, data->nb_icd_formats, hdc);
data->nb_sw_formats = sw_DescribePixelFormat(hdc, 0, 0, NULL);
data->next = dc_data_list;
dc_data_list = data;
@@ -927,6 +927,6 @@
{
context = CONTAINING_RECORD(Entry, struct wgl_context, ListEntry);
wglDeleteContext((HGLRC)context);
- Entry = ContextListHead.Flink;
- }
-}
+ Entry = Entry->Flink;
+ }
+}