wgl: GetPixelFormat fix for offscreen formats.

This commit is contained in:
Roderick Colenbrander 2007-08-01 14:38:49 +02:00 committed by Alexandre Julliard
parent aa225419f3
commit 219269c0f1
10 changed files with 258 additions and 1 deletions

4
.gitignore vendored
View File

@ -433,6 +433,9 @@ dlls/olepro32/version.res
dlls/olesvr.dll16 dlls/olesvr.dll16
dlls/olesvr32/libolesvr32.def dlls/olesvr32/libolesvr32.def
dlls/opengl32/libopengl32.def dlls/opengl32/libopengl32.def
dlls/opengl32/tests/*.ok
dlls/opengl32/tests/opengl32_crosstest.exe
dlls/opengl32/tests/testlist.c
dlls/opengl32/version.res dlls/opengl32/version.res
dlls/pdh/libpdh.def dlls/pdh/libpdh.def
dlls/pdh/tests/*.ok dlls/pdh/tests/*.ok
@ -894,6 +897,7 @@ programs/winetest/ntprint_test.exe
programs/winetest/odbccp32_test.exe programs/winetest/odbccp32_test.exe
programs/winetest/ole32_test.exe programs/winetest/ole32_test.exe
programs/winetest/oleaut32_test.exe programs/winetest/oleaut32_test.exe
programs/winetest/opengl32_test.exe
programs/winetest/pdh_test.exe programs/winetest/pdh_test.exe
programs/winetest/psapi_test.exe programs/winetest/psapi_test.exe
programs/winetest/quartz_test.exe programs/winetest/quartz_test.exe

View File

@ -333,6 +333,7 @@ ALL_MAKEFILES = \
dlls/olepro32/Makefile \ dlls/olepro32/Makefile \
dlls/olesvr32/Makefile \ dlls/olesvr32/Makefile \
dlls/opengl32/Makefile \ dlls/opengl32/Makefile \
dlls/opengl32/tests/Makefile \
dlls/pdh/Makefile \ dlls/pdh/Makefile \
dlls/pdh/tests/Makefile \ dlls/pdh/tests/Makefile \
dlls/powrprof/Makefile \ dlls/powrprof/Makefile \
@ -695,6 +696,7 @@ dlls/oledlg/Makefile: dlls/oledlg/Makefile.in dlls/Makedll.rules
dlls/olepro32/Makefile: dlls/olepro32/Makefile.in dlls/Makedll.rules dlls/olepro32/Makefile: dlls/olepro32/Makefile.in dlls/Makedll.rules
dlls/olesvr32/Makefile: dlls/olesvr32/Makefile.in dlls/Makedll.rules dlls/olesvr32/Makefile: dlls/olesvr32/Makefile.in dlls/Makedll.rules
dlls/opengl32/Makefile: dlls/opengl32/Makefile.in dlls/Makedll.rules dlls/opengl32/Makefile: dlls/opengl32/Makefile.in dlls/Makedll.rules
dlls/opengl32/tests/Makefile: dlls/opengl32/tests/Makefile.in dlls/Maketest.rules
dlls/pdh/Makefile: dlls/pdh/Makefile.in dlls/Makedll.rules dlls/pdh/Makefile: dlls/pdh/Makefile.in dlls/Makedll.rules
dlls/pdh/tests/Makefile: dlls/pdh/tests/Makefile.in dlls/Maketest.rules dlls/pdh/tests/Makefile: dlls/pdh/tests/Makefile.in dlls/Maketest.rules
dlls/powrprof/Makefile: dlls/powrprof/Makefile.in dlls/Makedll.rules dlls/powrprof/Makefile: dlls/powrprof/Makefile.in dlls/Makedll.rules

3
configure vendored
View File

@ -20616,6 +20616,8 @@ ac_config_files="$ac_config_files dlls/olesvr32/Makefile"
ac_config_files="$ac_config_files dlls/opengl32/Makefile" ac_config_files="$ac_config_files dlls/opengl32/Makefile"
ac_config_files="$ac_config_files dlls/opengl32/tests/Makefile"
ac_config_files="$ac_config_files dlls/pdh/Makefile" ac_config_files="$ac_config_files dlls/pdh/Makefile"
ac_config_files="$ac_config_files dlls/pdh/tests/Makefile" ac_config_files="$ac_config_files dlls/pdh/tests/Makefile"
@ -21701,6 +21703,7 @@ do
"dlls/olepro32/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/olepro32/Makefile" ;; "dlls/olepro32/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/olepro32/Makefile" ;;
"dlls/olesvr32/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/olesvr32/Makefile" ;; "dlls/olesvr32/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/olesvr32/Makefile" ;;
"dlls/opengl32/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/opengl32/Makefile" ;; "dlls/opengl32/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/opengl32/Makefile" ;;
"dlls/opengl32/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/opengl32/tests/Makefile" ;;
"dlls/pdh/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/pdh/Makefile" ;; "dlls/pdh/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/pdh/Makefile" ;;
"dlls/pdh/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/pdh/tests/Makefile" ;; "dlls/pdh/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/pdh/tests/Makefile" ;;
"dlls/powrprof/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/powrprof/Makefile" ;; "dlls/powrprof/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/powrprof/Makefile" ;;

View File

@ -1734,6 +1734,7 @@ AC_CONFIG_FILES([dlls/oledlg/Makefile])
AC_CONFIG_FILES([dlls/olepro32/Makefile]) AC_CONFIG_FILES([dlls/olepro32/Makefile])
AC_CONFIG_FILES([dlls/olesvr32/Makefile]) AC_CONFIG_FILES([dlls/olesvr32/Makefile])
AC_CONFIG_FILES([dlls/opengl32/Makefile]) AC_CONFIG_FILES([dlls/opengl32/Makefile])
AC_CONFIG_FILES([dlls/opengl32/tests/Makefile])
AC_CONFIG_FILES([dlls/pdh/Makefile]) AC_CONFIG_FILES([dlls/pdh/Makefile])
AC_CONFIG_FILES([dlls/pdh/tests/Makefile]) AC_CONFIG_FILES([dlls/pdh/tests/Makefile])
AC_CONFIG_FILES([dlls/powrprof/Makefile]) AC_CONFIG_FILES([dlls/powrprof/Makefile])

View File

@ -277,6 +277,7 @@ TESTSUBDIRS = \
odbccp32/tests \ odbccp32/tests \
ole32/tests \ ole32/tests \
oleaut32/tests \ oleaut32/tests \
opengl32/tests \
pdh/tests \ pdh/tests \
psapi/tests \ psapi/tests \
quartz/tests \ quartz/tests \

View File

@ -0,0 +1,13 @@
TOPSRCDIR = @top_srcdir@
TOPOBJDIR = ../../..
SRCDIR = @srcdir@
VPATH = @srcdir@
TESTDLL = opengl32.dll
IMPORTS = opengl32 user32 gdi32 kernel32
CTESTS = \
opengl.c
@MAKE_TEST_RULES@
@DEPENDENCIES@ # everything below this line is overwritten by make depend

View File

@ -0,0 +1,211 @@
/*
* Some tests for OpenGL functions
*
* Copyright (C) 2007 Roderick Colenbrander
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <windows.h>
#include <wingdi.h>
#include "wine/test.h"
#define MAX_FORMATS 256
typedef void* HPBUFFERARB;
/* WGL_ARB_extensions_string */
static const char* (WINAPI *pwglGetExtensionsStringARB)(HDC);
static int (WINAPI *pwglReleasePbufferDCARB)(HPBUFFERARB, HDC);
/* WGL_ARB_pixel_format */
static BOOL (WINAPI *pwglChoosePixelFormatARB)(HDC, const int *, const FLOAT *, UINT, int *, UINT *);
/* WGL_ARB_pbuffer */
#define WGL_DRAW_TO_PBUFFER_ARB 0x202D
static HPBUFFERARB* (WINAPI *pwglCreatePbufferARB)(HDC, int, int, int, const int *);
static HDC (WINAPI *pwglGetPbufferDCARB)(HPBUFFERARB);
static const char* wgl_extensions = NULL;
static void init_functions(void)
{
/* WGL_ARB_extensions_string */
pwglGetExtensionsStringARB = (void*)wglGetProcAddress("wglGetExtensionsStringARB");
/* WGL_ARB_pixel_format */
pwglChoosePixelFormatARB = (void*)wglGetProcAddress("wglChoosePixelFormatARB");
/* WGL_ARB_pbuffer */
pwglCreatePbufferARB = (void*)wglGetProcAddress("wglCreatePbufferARB");
pwglGetPbufferDCARB = (void*)wglGetProcAddress("wglGetPbufferDCARB");
pwglReleasePbufferDCARB = (void*)wglGetProcAddress("wglReleasePbufferDCARB");
}
static void test_pbuffers(HDC hdc)
{
const int iAttribList[] = { WGL_DRAW_TO_PBUFFER_ARB, 1, /* Request pbuffer support */
0 };
int iFormats[MAX_FORMATS];
unsigned int nOnscreenFormats;
unsigned int nFormats;
int i, res;
int iPixelFormat = 0;
nOnscreenFormats = DescribePixelFormat(hdc, 0, 0, NULL);
/* When you want to render to a pbuffer you need to call wglGetPbufferDCARB which
* returns a 'magic' HDC which you can then pass to wglMakeCurrent to switch rendering
* to the pbuffer. Below some tests are performed on what happens if you use standard WGL calls
* on this 'magic' HDC for both a pixelformat that support onscreen and offscreen rendering
* and a pixelformat that's only available for offscreen rendering (this means that only
* wglChoosePixelFormatARB and friends know about the format.
*
* The first thing we need are pixelformats with pbuffer capabilites.
*/
res = pwglChoosePixelFormatARB(hdc, iAttribList, NULL, MAX_FORMATS, iFormats, &nFormats);
if(res <= 0)
{
skip("No pbuffer compatible formats found while WGL_ARB_pbuffer is supported\n");
return;
}
trace("nOnscreenFormats: %d\n", nOnscreenFormats);
trace("Total number of pbuffer capable pixelformats: %d\n", nFormats);
/* Try to select an onscreen pixelformat out of the list */
for(i=0; i < nFormats; i++)
{
/* Check if the format is onscreen, if it is choose it */
if(iFormats[i] <= nOnscreenFormats)
{
iPixelFormat = iFormats[i];
trace("Selected iPixelFormat=%d\n", iPixelFormat);
break;
}
}
/* A video driver supports a large number of onscreen and offscreen pixelformats.
* The traditional WGL calls only see a subset of the whole pixelformat list. First
* of all they only see the onscreen formats (the offscreen formats are at the end of the
* pixelformat list) and second extended pixelformat capabilities are hidden from the
* standard WGL calls. Only functions that depend on WGL_ARB_pixel_format can see them.
*
* Below we check if the pixelformat is also supported onscreen.
*/
if(iPixelFormat != 0)
{
HDC pbuffer_hdc;
HPBUFFERARB pbuffer = pwglCreatePbufferARB(hdc, iPixelFormat, 640 /* width */, 480 /* height */, NULL);
if(!pbuffer)
skip("Pbuffer creation failed!\n");
/* Test the pixelformat returned by GetPixelFormat on a pbuffer as the behavior is not clear */
pbuffer_hdc = pwglGetPbufferDCARB(pbuffer);
res = GetPixelFormat(pbuffer_hdc);
ok(res == iPixelFormat, "Unexpected iPixelFormat=%d returned by GetPixelFormat for format %d\n", res, iPixelFormat);
trace("iPixelFormat returned by GetPixelFormat: %d\n", res);
trace("PixelFormat from wglChoosePixelFormatARB: %d\n", iPixelFormat);
pwglReleasePbufferDCARB(pbuffer, hdc);
}
else skip("Pbuffer test for onscreen pixelformat skipped as no onscreen format with pbuffer capabilities have been found\n");
/* Search for a real offscreen format */
for(i=0, iPixelFormat=0; i<nFormats; i++)
{
if(iFormats[i] > nOnscreenFormats)
{
iPixelFormat = iFormats[i];
trace("Selected iPixelFormat: %d\n", iPixelFormat);
break;
}
}
if(iPixelFormat != 0)
{
HDC pbuffer_hdc;
HPBUFFERARB pbuffer = pwglCreatePbufferARB(hdc, iPixelFormat, 640 /* width */, 480 /* height */, NULL);
if(!pbuffer)
skip("Pbuffer creation failed!\n");
/* Test the pixelformat returned by GetPixelFormat on a pbuffer as the behavior is not clear */
pbuffer_hdc = pwglGetPbufferDCARB(pbuffer);
res = GetPixelFormat(pbuffer_hdc);
ok(res == 1, "Unexpected iPixelFormat=%d (1 expected) returned by GetPixelFormat for offscreen format %d\n", res, iPixelFormat);
trace("iPixelFormat returned by GetPixelFormat: %d\n", res);
trace("PixelFormat from wglChoosePixelFormatARB: %d\n", iPixelFormat);
pwglReleasePbufferDCARB(pbuffer, hdc);
}
else skip("Pbuffer test for offscreen pixelformat skipped as no offscreen-only format with pbuffer capabilities has been found\n");
}
START_TEST(opengl)
{
HWND hwnd;
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1, /* version */
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
24, /* 24-bit color depth */
0, 0, 0, 0, 0, 0, /* color bits */
0, /* alpha buffer */
0, /* shift bit */
0, /* accumulation buffer */
0, 0, 0, 0, /* accum bits */
32, /* z-buffer */
0, /* stencil buffer */
0, /* auxiliary buffer */
PFD_MAIN_PLANE, /* main layer */
0, /* reserved */
0, 0, 0 /* layer masks */
};
hwnd = CreateWindow("static", "Title", WS_OVERLAPPEDWINDOW,
10, 10, 200, 200, NULL, NULL, NULL, NULL);
ok(hwnd != NULL, "err: %d\n", GetLastError());
if (hwnd)
{
HDC hdc;
int iPixelFormat, res;
HGLRC hglrc;
ShowWindow(hwnd, SW_SHOW);
hdc = GetDC(hwnd);
iPixelFormat = ChoosePixelFormat(hdc, &pfd);
ok(iPixelFormat > 0, "No pixelformat found!\n"); /* This should never happen as ChoosePixelFormat always returns a closest match */
res = SetPixelFormat(hdc, iPixelFormat, &pfd);
ok(res, "SetPixelformat failed: %x\n", GetLastError());
hglrc = wglCreateContext(hdc);
res = wglMakeCurrent(hdc, hglrc);
ok(res, "wglMakeCurrent failed!\n");
init_functions();
wgl_extensions = pwglGetExtensionsStringARB(hdc);
if(wgl_extensions == NULL) skip("Skipping opengl32 tests because this OpenGL implementation doesn't support WGL extensions!\n");
if(strstr(wgl_extensions, "WGL_ARB_pbuffer"))
test_pbuffers(hdc);
else
trace("WGL_ARB_pbuffer not supported, skipping pbuffer test\n");
DestroyWindow(hwnd);
}
}

View File

@ -1257,9 +1257,27 @@ int X11DRV_DescribePixelFormat(X11DRV_PDEVICE *physDev,
* Get the pixel-format id used by this DC * Get the pixel-format id used by this DC
*/ */
int X11DRV_GetPixelFormat(X11DRV_PDEVICE *physDev) { int X11DRV_GetPixelFormat(X11DRV_PDEVICE *physDev) {
TRACE("(%p): returns %d\n", physDev, physDev->current_pf); WineGLPixelFormat *fmt;
int tmp;
TRACE("(%p)\n", physDev);
fmt = ConvertPixelFormatWGLtoGLX(gdi_display, physDev->current_pf, TRUE, &tmp);
if(!fmt)
{
/* This happens on HDCs on which SetPixelFormat wasn't called yet */
ERR("Unable to find a WineGLPixelFormat for iPixelFormat=%d\n", physDev->current_pf);
return 0;
}
else if(fmt->offscreenOnly)
{
/* Offscreen formats can't be used with traditional WGL calls.
* As has been verified on Windows GetPixelFormat doesn't fail but returns iPixelFormat=1. */
TRACE("Returning iPixelFormat=1 for offscreen format: %d\n", fmt->iPixelFormat);
return 1;
}
return physDev->current_pf; return physDev->current_pf;
TRACE("(%p): returns %d\n", physDev, physDev->current_pf);
} }
/** /**

View File

@ -64,6 +64,7 @@ TESTBINS = \
odbccp32_test.exe \ odbccp32_test.exe \
ole32_test.exe \ ole32_test.exe \
oleaut32_test.exe \ oleaut32_test.exe \
opengl32_test.exe \
pdh_test.exe \ pdh_test.exe \
psapi_test.exe \ psapi_test.exe \
quartz_test.exe \ quartz_test.exe \
@ -172,6 +173,8 @@ ole32_test.exe: $(DLLDIR)/ole32/tests/ole32_test.exe$(DLLEXT)
cp $(DLLDIR)/ole32/tests/ole32_test.exe$(DLLEXT) $@ && $(STRIP) $@ cp $(DLLDIR)/ole32/tests/ole32_test.exe$(DLLEXT) $@ && $(STRIP) $@
oleaut32_test.exe: $(DLLDIR)/oleaut32/tests/oleaut32_test.exe$(DLLEXT) oleaut32_test.exe: $(DLLDIR)/oleaut32/tests/oleaut32_test.exe$(DLLEXT)
cp $(DLLDIR)/oleaut32/tests/oleaut32_test.exe$(DLLEXT) $@ && $(STRIP) $@ cp $(DLLDIR)/oleaut32/tests/oleaut32_test.exe$(DLLEXT) $@ && $(STRIP) $@
opengl32_test.exe: $(DLLDIR)/opengl32/tests/opengl32_test.exe$(DLLEXT)
cp $(DLLDIR)/opengl32/tests/opengl32_test.exe$(DLLEXT) $@ && $(STRIP) $@
pdh_test.exe: $(DLLDIR)/pdh/tests/pdh_test.exe$(DLLEXT) pdh_test.exe: $(DLLDIR)/pdh/tests/pdh_test.exe$(DLLEXT)
cp $(DLLDIR)/pdh/tests/pdh_test.exe$(DLLEXT) $@ && $(STRIP) $@ cp $(DLLDIR)/pdh/tests/pdh_test.exe$(DLLEXT) $@ && $(STRIP) $@
psapi_test.exe: $(DLLDIR)/psapi/tests/psapi_test.exe$(DLLEXT) psapi_test.exe: $(DLLDIR)/psapi/tests/psapi_test.exe$(DLLEXT)

View File

@ -187,6 +187,7 @@ ntprint_test.exe TESTRES "ntprint_test.exe"
odbccp32_test.exe TESTRES "odbccp32_test.exe" odbccp32_test.exe TESTRES "odbccp32_test.exe"
ole32_test.exe TESTRES "ole32_test.exe" ole32_test.exe TESTRES "ole32_test.exe"
oleaut32_test.exe TESTRES "oleaut32_test.exe" oleaut32_test.exe TESTRES "oleaut32_test.exe"
opengl32_test.exe TESTRES "opengl32_test.exe"
pdh_test.exe TESTRES "pdh_test.exe" pdh_test.exe TESTRES "pdh_test.exe"
psapi_test.exe TESTRES "psapi_test.exe" psapi_test.exe TESTRES "psapi_test.exe"
quartz_test.exe TESTRES "quartz_test.exe" quartz_test.exe TESTRES "quartz_test.exe"