mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 03:23:51 +00:00
[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. svn path=/trunk/; revision=74207
This commit is contained in:
parent
2d7b980fca
commit
ad61fd2df2
2 changed files with 113 additions and 43 deletions
|
@ -11,16 +11,27 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(opengl32);
|
WINE_DEFAULT_DEBUG_CHANNEL(opengl32);
|
||||||
|
|
||||||
struct Drv_Opengl_Info
|
typedef struct
|
||||||
{
|
{
|
||||||
DWORD Version; /*!< Driver interface version */
|
DWORD Version; /*!< Driver interface version */
|
||||||
DWORD DriverVersion; /*!< Driver version */
|
DWORD DriverVersion; /*!< Driver version */
|
||||||
WCHAR DriverName[256]; /*!< Driver name */
|
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 CRITICAL_SECTION icdload_cs = {NULL, -1, 0, 0, 0, 0};
|
||||||
static struct ICD_Data* ICD_Data_List = NULL;
|
static struct ICD_Data* ICD_Data_List = NULL;
|
||||||
static const WCHAR OpenGLDrivers_Key[] = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\OpenGLDrivers";
|
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)
|
static void APIENTRY wglSetCurrentValue(PVOID value)
|
||||||
{
|
{
|
||||||
|
@ -47,41 +58,99 @@ struct ICD_Data* IntGetIcdData(HDC hdc)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
DWORD dwInput, dwValueType, Version, DriverVersion, Flags;
|
DWORD dwInput, dwValueType, Version, DriverVersion, Flags;
|
||||||
struct Drv_Opengl_Info DrvInfo;
|
Drv_Opengl_Info DrvInfo;
|
||||||
|
pDrv_Opengl_Info pDrvInfo;
|
||||||
struct ICD_Data* data;
|
struct ICD_Data* data;
|
||||||
HKEY OglKey, DrvKey;
|
HKEY OglKey, DrvKey, CustomKey;
|
||||||
WCHAR DllName[MAX_PATH];
|
WCHAR DllName[MAX_PATH];
|
||||||
BOOL (WINAPI *DrvValidateVersion)(DWORD);
|
BOOL (WINAPI *DrvValidateVersion)(DWORD);
|
||||||
void (WINAPI *DrvSetCallbackProcs)(int nProcs, PROC* pProcs);
|
void (WINAPI *DrvSetCallbackProcs)(int nProcs, PROC* pProcs);
|
||||||
|
|
||||||
/* First, see if the driver supports this */
|
/* The following code is ReactOS specific and allows us to easily load an arbitrary ICD:
|
||||||
dwInput = OPENGL_GETINFO;
|
* It checks HKCU\Software\ReactOS\OpenGL for a custom ICD and will always load it
|
||||||
ret = ExtEscape(hdc,
|
* no matter what driver the DC is associated with. It can also force using the
|
||||||
QUERYESCSUPPORT,
|
* built-in Software Implementation*/
|
||||||
sizeof(DWORD),
|
if(CustomDriverState == OGL_CD_NOT_QUERIED)
|
||||||
(LPCSTR)&dwInput,
|
{
|
||||||
0,
|
/* Only do this once so there's not any significant performance penalty */
|
||||||
NULL);
|
CustomDriverState = OGL_CD_NONE;
|
||||||
|
memset(&CustomDrvInfo, 0, sizeof(Drv_Opengl_Info));
|
||||||
if(ret <= 0)
|
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
/* Driver doesn't support opengl */
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* 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");
|
/* First, see if the driver supports this */
|
||||||
return NULL;
|
dwInput = OPENGL_GETINFO;
|
||||||
|
ret = ExtEscape(hdc, QUERYESCSUPPORT, sizeof(DWORD), (LPCSTR)&dwInput, 0, NULL);
|
||||||
|
|
||||||
|
/* Driver doesn't support opengl */
|
||||||
|
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*/
|
/* Protect the list while we are loading*/
|
||||||
|
@ -91,7 +160,7 @@ struct ICD_Data* IntGetIcdData(HDC hdc)
|
||||||
data = ICD_Data_List;
|
data = ICD_Data_List;
|
||||||
while(data)
|
while(data)
|
||||||
{
|
{
|
||||||
if(!_wcsicmp(data->DriverName, DrvInfo.DriverName))
|
if(!_wcsicmp(data->DriverName, pDrvInfo->DriverName))
|
||||||
{
|
{
|
||||||
/* Found it */
|
/* Found it */
|
||||||
TRACE("Found already loaded %p.\n", data);
|
TRACE("Found already loaded %p.\n", data);
|
||||||
|
@ -108,16 +177,16 @@ struct ICD_Data* IntGetIcdData(HDC hdc)
|
||||||
ERR("Failed to open the OpenGLDrivers key.\n");
|
ERR("Failed to open the OpenGLDrivers key.\n");
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
ret = RegOpenKeyExW(OglKey, DrvInfo.DriverName, 0, KEY_READ, &DrvKey);
|
ret = RegOpenKeyExW(OglKey, pDrvInfo->DriverName, 0, KEY_READ, &DrvKey);
|
||||||
if(ret != ERROR_SUCCESS)
|
if(ret != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Some driver installer just provide the DLL name, like the Matrox G400 */
|
/* 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);
|
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))
|
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);
|
RegCloseKey(OglKey);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
@ -127,7 +196,7 @@ struct ICD_Data* IntGetIcdData(HDC hdc)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The driver have a subkey for the ICD */
|
/* 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);
|
dwInput = sizeof(DllName);
|
||||||
ret = RegQueryValueExW(DrvKey, L"Dll", 0, &dwValueType, (LPBYTE)DllName, &dwInput);
|
ret = RegQueryValueExW(DrvKey, L"Dll", 0, &dwValueType, (LPBYTE)DllName, &dwInput);
|
||||||
if((ret != ERROR_SUCCESS) || (dwValueType != REG_SZ))
|
if((ret != ERROR_SUCCESS) || (dwValueType != REG_SZ))
|
||||||
|
@ -144,9 +213,9 @@ struct ICD_Data* IntGetIcdData(HDC hdc)
|
||||||
{
|
{
|
||||||
WARN("No version in driver subkey\n");
|
WARN("No version in driver subkey\n");
|
||||||
}
|
}
|
||||||
else if(Version != DrvInfo.Version)
|
else if(Version != pDrvInfo->Version)
|
||||||
{
|
{
|
||||||
ERR("Version mismatch between registry (%lu) and display driver (%lu).\n", Version, DrvInfo.Version);
|
ERR("Version mismatch between registry (%lu) and display driver (%lu).\n", Version, pDrvInfo->Version);
|
||||||
RegCloseKey(DrvKey);
|
RegCloseKey(DrvKey);
|
||||||
RegCloseKey(OglKey);
|
RegCloseKey(OglKey);
|
||||||
goto end;
|
goto end;
|
||||||
|
@ -158,9 +227,9 @@ struct ICD_Data* IntGetIcdData(HDC hdc)
|
||||||
{
|
{
|
||||||
WARN("No driver version in driver subkey\n");
|
WARN("No driver version in driver subkey\n");
|
||||||
}
|
}
|
||||||
else if(DriverVersion != DrvInfo.DriverVersion)
|
else if(DriverVersion != pDrvInfo->DriverVersion)
|
||||||
{
|
{
|
||||||
ERR("Driver version mismatch between registry (%lu) and display driver (%lu).\n", DriverVersion, DrvInfo.DriverVersion);
|
ERR("Driver version mismatch between registry (%lu) and display driver (%lu).\n", DriverVersion, pDrvInfo->DriverVersion);
|
||||||
RegCloseKey(DrvKey);
|
RegCloseKey(DrvKey);
|
||||||
RegCloseKey(OglKey);
|
RegCloseKey(OglKey);
|
||||||
goto end;
|
goto end;
|
||||||
|
@ -206,7 +275,7 @@ struct ICD_Data* IntGetIcdData(HDC hdc)
|
||||||
DrvValidateVersion = (void*)GetProcAddress(data->hModule, "DrvValidateVersion");
|
DrvValidateVersion = (void*)GetProcAddress(data->hModule, "DrvValidateVersion");
|
||||||
if(DrvValidateVersion)
|
if(DrvValidateVersion)
|
||||||
{
|
{
|
||||||
if(!DrvValidateVersion(DrvInfo.DriverVersion))
|
if(!DrvValidateVersion(pDrvInfo->DriverVersion))
|
||||||
{
|
{
|
||||||
ERR("DrvValidateVersion failed!.\n");
|
ERR("DrvValidateVersion failed!.\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -262,13 +331,14 @@ struct ICD_Data* IntGetIcdData(HDC hdc)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the DriverName */
|
/* Copy the DriverName */
|
||||||
wcscpy(data->DriverName, DrvInfo.DriverName);
|
wcscpy(data->DriverName, pDrvInfo->DriverName);
|
||||||
|
|
||||||
/* Push the list */
|
/* Push the list */
|
||||||
data->next = ICD_Data_List;
|
data->next = ICD_Data_List;
|
||||||
ICD_Data_List = data;
|
ICD_Data_List = data;
|
||||||
|
|
||||||
TRACE("Returning %p.\n", data);
|
TRACE("Returning %p.\n", data);
|
||||||
|
TRACE("ICD driver %S (%S) successfully loaded.\n", pDrvInfo->DriverName, DllName);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
/* Unlock and return */
|
/* Unlock and return */
|
||||||
|
|
|
@ -79,7 +79,7 @@ get_dc_data(HDC hdc)
|
||||||
data->nb_icd_formats = data->icd_data->DrvDescribePixelFormat(hdc, 0, 0, NULL);
|
data->nb_icd_formats = data->icd_data->DrvDescribePixelFormat(hdc, 0, 0, NULL);
|
||||||
else
|
else
|
||||||
data->nb_icd_formats = 0;
|
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->nb_sw_formats = sw_DescribePixelFormat(hdc, 0, 0, NULL);
|
||||||
data->next = dc_data_list;
|
data->next = dc_data_list;
|
||||||
dc_data_list = data;
|
dc_data_list = data;
|
||||||
|
@ -927,6 +927,6 @@ IntDeleteAllContexts(void)
|
||||||
{
|
{
|
||||||
context = CONTAINING_RECORD(Entry, struct wgl_context, ListEntry);
|
context = CONTAINING_RECORD(Entry, struct wgl_context, ListEntry);
|
||||||
wglDeleteContext((HGLRC)context);
|
wglDeleteContext((HGLRC)context);
|
||||||
Entry = ContextListHead.Flink;
|
Entry = Entry->Flink;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue