-- v5: win32u: Add a nulldrv pbuffer stub implementation. winemac: Use the generic pbuffer implementation. winewayland: Use the generic pbuffer implementation. win32u: Introduce a generic pbuffer implementation from winex11. opengl32/tests: Add more WGL_ARB_render_texture tests. opengl32/tests: Add more WGL_ARB_pbuffer tests. opengl32/tests: Avoid leaking contexts. win32u: Handle some pixel format initialization.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 148 ++++++++++++++++++++-------------- dlls/wineandroid.drv/opengl.c | 120 +++++++++++++-------------- dlls/winemac.drv/opengl.c | 48 +++++------ dlls/winewayland.drv/opengl.c | 42 +++++----- dlls/winex11.drv/opengl.c | 55 +++++-------- include/wine/opengl_driver.h | 2 + 6 files changed, 201 insertions(+), 214 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 36db698edae..9686f64ab2b 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -41,6 +41,59 @@ WINE_DEFAULT_DEBUG_CHANNEL(wgl);
static struct opengl_funcs *get_dc_funcs( HDC hdc, void *null_funcs );
+static const struct +{ + BYTE color_bits; + BYTE red_bits, red_shift; + BYTE green_bits, green_shift; + BYTE blue_bits, blue_shift; + BYTE alpha_bits, alpha_shift; + BYTE accum_bits; + BYTE depth_bits; + BYTE stencil_bits; +} pixel_formats[] = +{ + { 32, 8, 16, 8, 8, 8, 0, 8, 24, 16, 32, 8 }, + { 32, 8, 16, 8, 8, 8, 0, 8, 24, 16, 16, 8 }, + { 32, 8, 0, 8, 8, 8, 16, 8, 24, 16, 32, 8 }, + { 32, 8, 0, 8, 8, 8, 16, 8, 24, 16, 16, 8 }, + { 32, 8, 8, 8, 16, 8, 24, 8, 0, 16, 32, 8 }, + { 32, 8, 8, 8, 16, 8, 24, 8, 0, 16, 16, 8 }, + { 24, 8, 0, 8, 8, 8, 16, 0, 0, 16, 32, 8 }, + { 24, 8, 0, 8, 8, 8, 16, 0, 0, 16, 16, 8 }, + { 24, 8, 16, 8, 8, 8, 0, 0, 0, 16, 32, 8 }, + { 24, 8, 16, 8, 8, 8, 0, 0, 0, 16, 16, 8 }, + { 16, 5, 0, 6, 5, 5, 11, 0, 0, 16, 32, 8 }, + { 16, 5, 0, 6, 5, 5, 11, 0, 0, 16, 16, 8 }, +}; + +static void describe_pixel_format( int fmt, PIXELFORMATDESCRIPTOR *descr ) +{ + memset( descr, 0, sizeof(*descr) ); + descr->nSize = sizeof(*descr); + descr->nVersion = 1; + descr->dwFlags = PFD_SUPPORT_GDI | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_BITMAP | PFD_GENERIC_FORMAT; + descr->iPixelType = PFD_TYPE_RGBA; + descr->cColorBits = pixel_formats[fmt - 1].color_bits; + descr->cRedBits = pixel_formats[fmt - 1].red_bits; + descr->cRedShift = pixel_formats[fmt - 1].red_shift; + descr->cGreenBits = pixel_formats[fmt - 1].green_bits; + descr->cGreenShift = pixel_formats[fmt - 1].green_shift; + descr->cBlueBits = pixel_formats[fmt - 1].blue_bits; + descr->cBlueShift = pixel_formats[fmt - 1].blue_shift; + descr->cAlphaBits = pixel_formats[fmt - 1].alpha_bits; + descr->cAlphaShift = pixel_formats[fmt - 1].alpha_shift; + descr->cAccumBits = pixel_formats[fmt - 1].accum_bits; + descr->cAccumRedBits = pixel_formats[fmt - 1].accum_bits / 4; + descr->cAccumGreenBits = pixel_formats[fmt - 1].accum_bits / 4; + descr->cAccumBlueBits = pixel_formats[fmt - 1].accum_bits / 4; + descr->cAccumAlphaBits = pixel_formats[fmt - 1].accum_bits / 4; + descr->cDepthBits = pixel_formats[fmt - 1].depth_bits; + descr->cStencilBits = pixel_formats[fmt - 1].stencil_bits; + descr->cAuxBuffers = 0; + descr->iLayerType = PFD_MAIN_PLANE; +} + static BOOL has_extension( const char *list, const char *ext ) { size_t len = strlen( ext ); @@ -220,59 +273,6 @@ static BOOL osmesa_make_current( struct wgl_context *context, void *bits, return ret; }
-static const struct -{ - BYTE color_bits; - BYTE red_bits, red_shift; - BYTE green_bits, green_shift; - BYTE blue_bits, blue_shift; - BYTE alpha_bits, alpha_shift; - BYTE accum_bits; - BYTE depth_bits; - BYTE stencil_bits; -} pixel_formats[] = -{ - { 32, 8, 16, 8, 8, 8, 0, 8, 24, 16, 32, 8 }, - { 32, 8, 16, 8, 8, 8, 0, 8, 24, 16, 16, 8 }, - { 32, 8, 0, 8, 8, 8, 16, 8, 24, 16, 32, 8 }, - { 32, 8, 0, 8, 8, 8, 16, 8, 24, 16, 16, 8 }, - { 32, 8, 8, 8, 16, 8, 24, 8, 0, 16, 32, 8 }, - { 32, 8, 8, 8, 16, 8, 24, 8, 0, 16, 16, 8 }, - { 24, 8, 0, 8, 8, 8, 16, 0, 0, 16, 32, 8 }, - { 24, 8, 0, 8, 8, 8, 16, 0, 0, 16, 16, 8 }, - { 24, 8, 16, 8, 8, 8, 0, 0, 0, 16, 32, 8 }, - { 24, 8, 16, 8, 8, 8, 0, 0, 0, 16, 16, 8 }, - { 16, 5, 0, 6, 5, 5, 11, 0, 0, 16, 32, 8 }, - { 16, 5, 0, 6, 5, 5, 11, 0, 0, 16, 16, 8 }, -}; - -static void describe_pixel_format( int fmt, PIXELFORMATDESCRIPTOR *descr ) -{ - memset( descr, 0, sizeof(*descr) ); - descr->nSize = sizeof(*descr); - descr->nVersion = 1; - descr->dwFlags = PFD_SUPPORT_GDI | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_BITMAP | PFD_GENERIC_FORMAT; - descr->iPixelType = PFD_TYPE_RGBA; - descr->cColorBits = pixel_formats[fmt - 1].color_bits; - descr->cRedBits = pixel_formats[fmt - 1].red_bits; - descr->cRedShift = pixel_formats[fmt - 1].red_shift; - descr->cGreenBits = pixel_formats[fmt - 1].green_bits; - descr->cGreenShift = pixel_formats[fmt - 1].green_shift; - descr->cBlueBits = pixel_formats[fmt - 1].blue_bits; - descr->cBlueShift = pixel_formats[fmt - 1].blue_shift; - descr->cAlphaBits = pixel_formats[fmt - 1].alpha_bits; - descr->cAlphaShift = pixel_formats[fmt - 1].alpha_shift; - descr->cAccumBits = pixel_formats[fmt - 1].accum_bits; - descr->cAccumRedBits = pixel_formats[fmt - 1].accum_bits / 4; - descr->cAccumGreenBits = pixel_formats[fmt - 1].accum_bits / 4; - descr->cAccumBlueBits = pixel_formats[fmt - 1].accum_bits / 4; - descr->cAccumAlphaBits = pixel_formats[fmt - 1].accum_bits / 4; - descr->cDepthBits = pixel_formats[fmt - 1].depth_bits; - descr->cStencilBits = pixel_formats[fmt - 1].stencil_bits; - descr->cAuxBuffers = 0; - descr->iLayerType = PFD_MAIN_PLANE; -} - static BOOL osmesa_wglCopyContext( struct wgl_context *src, struct wgl_context *dst, UINT mask ) { FIXME( "not supported yet\n" ); @@ -377,6 +377,19 @@ static struct opengl_funcs *osmesa_get_wgl_driver(void)
#endif /* SONAME_LIBOSMESA */
+static UINT nulldrv_init_pixel_formats( UINT *onscreen_count ) +{ + *onscreen_count = ARRAY_SIZE(pixel_formats); + return ARRAY_SIZE(pixel_formats); +} + +static BOOL nulldrv_describe_pixel_format( int format, struct wgl_pixel_format *desc ) +{ + if (format <= 0 || format > ARRAY_SIZE(pixel_formats)) return FALSE; + describe_pixel_format( format, &desc->pfd ); + return TRUE; +} + static const char *nulldrv_init_wgl_extensions(void) { return ""; @@ -389,10 +402,13 @@ static BOOL nulldrv_set_pixel_format( HWND hwnd, int old_format, int new_format,
static const struct opengl_driver_funcs nulldrv_funcs = { + .p_init_pixel_formats = nulldrv_init_pixel_formats, + .p_describe_pixel_format = nulldrv_describe_pixel_format, .p_init_wgl_extensions = nulldrv_init_wgl_extensions, .p_set_pixel_format = nulldrv_set_pixel_format, }; static const struct opengl_driver_funcs *driver_funcs = &nulldrv_funcs; +static UINT formats_count, onscreen_count;
static char wgl_extensions[4096];
@@ -422,18 +438,13 @@ static int win32u_wglGetPixelFormat( HDC hdc ) else if ((dc = get_dc_ptr( hdc ))) { BOOL is_display = dc->is_display; - UINT total, onscreen; ret = dc->pixel_format; release_dc_ptr( dc );
- if (is_display && ret >= 0) - { - /* Offscreen formats can't be used with traditional WGL calls. As has been - * verified on Windows GetPixelFormat doesn't fail but returns 1. - */ - display_funcs->p_get_pixel_formats( NULL, 0, &total, &onscreen ); - if (ret > onscreen) ret = 1; - } + /* Offscreen formats can't be used with traditional WGL calls. As has been + * verified on Windows GetPixelFormat doesn't fail but returns 1. + */ + if (is_display && ret >= 0 && ret > onscreen_count) ret = 1; }
TRACE( "%p/%p -> %d\n", hdc, hwnd, ret ); @@ -481,6 +492,16 @@ static BOOL win32u_wglSetPixelFormatWINE( HDC hdc, int format ) return set_dc_pixel_format( hdc, format, TRUE ); }
+static void win32u_get_pixel_formats( struct wgl_pixel_format *formats, UINT max_formats, + UINT *num_formats, UINT *num_onscreen_formats ) +{ + UINT i = 0; + + if (formats) while (i < max_formats && driver_funcs->p_describe_pixel_format( i + 1, &formats[i] )) i++; + *num_formats = formats_count; + *num_onscreen_formats = onscreen_count; +} + static void memory_funcs_init(void) { memory_funcs = osmesa_get_wgl_driver(); @@ -500,8 +521,11 @@ static void display_funcs_init(void) ERR( "Failed to initialize the driver opengl functions, status %#x\n", status ); return; } + if (display_funcs && !(formats_count = driver_funcs->p_init_pixel_formats( &onscreen_count ))) display_funcs = NULL; if (!display_funcs) return;
+ display_funcs->p_get_pixel_formats = win32u_get_pixel_formats; + strcpy( wgl_extensions, driver_funcs->p_init_wgl_extensions() ); display_funcs->p_wglGetPixelFormat = win32u_wglGetPixelFormat; display_funcs->p_wglSetPixelFormat = win32u_wglSetPixelFormat; diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index c6c42a3bf2b..9b48b9d3ba0 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -244,11 +244,15 @@ static struct wgl_context *create_context( HDC hdc, struct wgl_context *share, c return ctx; }
-static void describe_pixel_format( struct egl_pixel_format *fmt, PIXELFORMATDESCRIPTOR *pfd ) +static BOOL android_describe_pixel_format( int format, struct wgl_pixel_format *desc ) { + struct egl_pixel_format *fmt = pixel_formats + format - 1; + PIXELFORMATDESCRIPTOR *pfd = &desc->pfd; EGLint val; EGLConfig config = fmt->config;
+ if (format <= 0 || format > nb_pixel_formats) return FALSE; + memset( pfd, 0, sizeof(*pfd) ); pfd->nSize = sizeof(*pfd); pfd->nVersion = 1; @@ -275,6 +279,7 @@ static void describe_pixel_format( struct egl_pixel_format *fmt, PIXELFORMATDESC pfd->cBlueShift = pfd->cAlphaShift + pfd->cAlphaBits; pfd->cGreenShift = pfd->cBlueShift + pfd->cBlueBits; pfd->cRedShift = pfd->cGreenShift + pfd->cGreenBits; + return TRUE; }
/*********************************************************************** @@ -505,24 +510,6 @@ static BOOL android_wglSwapBuffers( HDC hdc ) return TRUE; }
-/********************************************************************** - * android_get_pixel_formats - */ -static void android_get_pixel_formats( struct wgl_pixel_format *formats, - UINT max_formats, UINT *num_formats, - UINT *num_onscreen_formats ) -{ - UINT i; - - if (formats) - { - for (i = 0; i < min( max_formats, nb_pixel_formats ); ++i) - describe_pixel_format( &pixel_formats[i], &formats[i].pfd ); - } - *num_formats = nb_pixel_formats; - *num_onscreen_formats = nb_onscreen_formats; -} - static void wglFinish(void) { struct wgl_context *ctx = NtCurrentTeb()->glContext; @@ -863,8 +850,59 @@ static void init_opengl_funcs(void) #undef REDIRECT }
+static UINT android_init_pixel_formats( UINT *onscreen_count ) +{ + EGLConfig *configs; + EGLint count, i, pass; + + p_eglGetConfigs( display, NULL, 0, &count ); + configs = malloc( count * sizeof(*configs) ); + pixel_formats = malloc( count * sizeof(*pixel_formats) ); + p_eglGetConfigs( display, configs, count, &count ); + if (!count || !configs || !pixel_formats) + { + free( configs ); + free( pixel_formats ); + ERR( "eglGetConfigs returned no configs\n" ); + return 0; + } + + for (pass = 0; pass < 2; pass++) + { + for (i = 0; i < count; i++) + { + EGLint id, type, visual_id, native, render, color, r, g, b, d, s; + + p_eglGetConfigAttrib( display, configs[i], EGL_SURFACE_TYPE, &type ); + if (!(type & EGL_WINDOW_BIT) == !pass) continue; + p_eglGetConfigAttrib( display, configs[i], EGL_RENDERABLE_TYPE, &render ); + if (egl_client_version == 2 && !(render & EGL_OPENGL_ES2_BIT)) continue; + + pixel_formats[nb_pixel_formats++].config = configs[i]; + + p_eglGetConfigAttrib( display, configs[i], EGL_CONFIG_ID, &id ); + p_eglGetConfigAttrib( display, configs[i], EGL_NATIVE_VISUAL_ID, &visual_id ); + p_eglGetConfigAttrib( display, configs[i], EGL_NATIVE_RENDERABLE, &native ); + p_eglGetConfigAttrib( display, configs[i], EGL_COLOR_BUFFER_TYPE, &color ); + p_eglGetConfigAttrib( display, configs[i], EGL_RED_SIZE, &r ); + p_eglGetConfigAttrib( display, configs[i], EGL_GREEN_SIZE, &g ); + p_eglGetConfigAttrib( display, configs[i], EGL_BLUE_SIZE, &b ); + p_eglGetConfigAttrib( display, configs[i], EGL_DEPTH_SIZE, &d ); + p_eglGetConfigAttrib( display, configs[i], EGL_STENCIL_SIZE, &s ); + TRACE( "%u: config %u id %u type %x visual %u native %u render %x colortype %u rgb %u,%u,%u depth %u stencil %u\n", + nb_pixel_formats, i, id, type, visual_id, native, render, color, r, g, b, d, s ); + } + if (!pass) nb_onscreen_formats = nb_pixel_formats; + } + + *onscreen_count = nb_onscreen_formats; + return nb_pixel_formats; +} + static const struct opengl_driver_funcs android_driver_funcs = { + .p_init_pixel_formats = android_init_pixel_formats, + .p_describe_pixel_format = android_describe_pixel_format, .p_init_wgl_extensions = android_init_wgl_extensions, .p_set_pixel_format = android_set_pixel_format, }; @@ -874,8 +912,7 @@ static const struct opengl_driver_funcs android_driver_funcs = */ UINT ANDROID_OpenGLInit( UINT version, struct opengl_funcs **funcs, const struct opengl_driver_funcs **driver_funcs ) { - EGLConfig *configs; - EGLint major, minor, count, i, pass; + EGLint major, minor;
if (version != WINE_OPENGL_DRIVER_VERSION) { @@ -916,46 +953,6 @@ UINT ANDROID_OpenGLInit( UINT version, struct opengl_funcs **funcs, const struct if (!p_eglInitialize( display, &major, &minor )) return 0; TRACE( "display %p version %u.%u\n", display, major, minor );
- p_eglGetConfigs( display, NULL, 0, &count ); - configs = malloc( count * sizeof(*configs) ); - pixel_formats = malloc( count * sizeof(*pixel_formats) ); - p_eglGetConfigs( display, configs, count, &count ); - if (!count || !configs || !pixel_formats) - { - free( configs ); - free( pixel_formats ); - ERR( "eglGetConfigs returned no configs\n" ); - return 0; - } - - for (pass = 0; pass < 2; pass++) - { - for (i = 0; i < count; i++) - { - EGLint id, type, visual_id, native, render, color, r, g, b, d, s; - - p_eglGetConfigAttrib( display, configs[i], EGL_SURFACE_TYPE, &type ); - if (!(type & EGL_WINDOW_BIT) == !pass) continue; - p_eglGetConfigAttrib( display, configs[i], EGL_RENDERABLE_TYPE, &render ); - if (egl_client_version == 2 && !(render & EGL_OPENGL_ES2_BIT)) continue; - - pixel_formats[nb_pixel_formats++].config = configs[i]; - - p_eglGetConfigAttrib( display, configs[i], EGL_CONFIG_ID, &id ); - p_eglGetConfigAttrib( display, configs[i], EGL_NATIVE_VISUAL_ID, &visual_id ); - p_eglGetConfigAttrib( display, configs[i], EGL_NATIVE_RENDERABLE, &native ); - p_eglGetConfigAttrib( display, configs[i], EGL_COLOR_BUFFER_TYPE, &color ); - p_eglGetConfigAttrib( display, configs[i], EGL_RED_SIZE, &r ); - p_eglGetConfigAttrib( display, configs[i], EGL_GREEN_SIZE, &g ); - p_eglGetConfigAttrib( display, configs[i], EGL_BLUE_SIZE, &b ); - p_eglGetConfigAttrib( display, configs[i], EGL_DEPTH_SIZE, &d ); - p_eglGetConfigAttrib( display, configs[i], EGL_STENCIL_SIZE, &s ); - TRACE( "%u: config %u id %u type %x visual %u native %u render %x colortype %u rgb %u,%u,%u depth %u stencil %u\n", - nb_pixel_formats, i, id, type, visual_id, native, render, color, r, g, b, d, s ); - } - if (!pass) nb_onscreen_formats = nb_pixel_formats; - } - init_opengl_funcs(); *funcs = &egl_funcs; *driver_funcs = &android_driver_funcs; @@ -985,7 +982,6 @@ static struct opengl_funcs egl_funcs = .p_wglMakeCurrent = android_wglMakeCurrent, .p_wglShareLists = android_wglShareLists, .p_wglSwapBuffers = android_wglSwapBuffers, - .p_get_pixel_formats = android_get_pixel_formats, #define USE_GL_FUNC(name) .p_##name = (void *)glstub_##name, ALL_GL_FUNCS #undef USE_GL_FUNC diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index 429c3913f6d..a9a4dc53da0 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -1106,9 +1106,8 @@ static CFComparisonResult pixel_format_comparator(const void *val1, const void * }
-static BOOL init_pixel_formats(void) +static UINT macdrv_init_pixel_formats(UINT *onscreen_count) { - BOOL ret = FALSE; CGLRendererInfoObj renderer_info; GLint rendererCount; CGLError err; @@ -1123,7 +1122,7 @@ static BOOL init_pixel_formats(void) if (err) { WARN("CGLQueryRendererInfo failed (%d) %s\n", err, CGLErrorString(err)); - return FALSE; + return 0; }
pixel_format_set = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks); @@ -1131,7 +1130,7 @@ static BOOL init_pixel_formats(void) { WARN("CFSetCreateMutable failed\n"); CGLDestroyRendererInfo(renderer_info); - return FALSE; + return 0; }
pixel_format_array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); @@ -1140,7 +1139,7 @@ static BOOL init_pixel_formats(void) WARN("CFArrayCreateMutable failed\n"); CFRelease(pixel_format_set); CGLDestroyRendererInfo(renderer_info); - return FALSE; + return 0; }
for (i = 0; i < rendererCount; i++) @@ -1180,16 +1179,20 @@ static BOOL init_pixel_formats(void)
nb_formats = range.length; TRACE("Total number of unique pixel formats: %d\n", nb_formats); - ret = TRUE; } else + { WARN("failed to allocate pixel format list\n"); + nb_formats = 0; + } } else WARN("got no pixel formats\n");
CFRelease(pixel_format_array); - return ret; + + *onscreen_count = nb_displayable_formats; + return nb_formats; }
@@ -3498,9 +3501,6 @@ UINT macdrv_OpenGLInit(UINT version, struct opengl_funcs **funcs, const struct o if (gluCheckExtension((GLubyte*)"GL_APPLE_flush_render", (GLubyte*)gl_info.glExtensions)) pglFlushRenderAPPLE = dlsym(opengl_handle, "glFlushRenderAPPLE");
- if (!init_pixel_formats()) - goto failed; - *funcs = &opengl_funcs; *driver_funcs = &macdrv_driver_funcs; return STATUS_SUCCESS; @@ -3535,10 +3535,13 @@ void sync_gl_view(struct macdrv_win_data* data, const struct window_rects *old_r }
-static void describe_pixel_format(const pixel_format *pf, struct wgl_pixel_format *descr) +static BOOL macdrv_describe_pixel_format(int format, struct wgl_pixel_format *descr) { + const pixel_format *pf = pixel_formats + format - 1; const struct color_mode *mode;
+ if (format <= 0 || format > nb_formats) return FALSE; + memset(descr, 0, sizeof(*descr)); descr->pfd.nSize = sizeof(*descr); descr->pfd.nVersion = 1; @@ -3618,6 +3621,8 @@ static void describe_pixel_format(const pixel_format *pf, struct wgl_pixel_forma descr->max_pbuffer_width = gl_info.max_viewport_dims[0]; descr->max_pbuffer_height = gl_info.max_viewport_dims[1]; descr->max_pbuffer_pixels = gl_info.max_viewport_dims[0] * gl_info.max_viewport_dims[1]; + + return TRUE; }
/*********************************************************************** @@ -3821,26 +3826,10 @@ static BOOL macdrv_wglSwapBuffers(HDC hdc) return TRUE; }
-/********************************************************************** - * macdrv_get_pixel_formats - */ -static void macdrv_get_pixel_formats(struct wgl_pixel_format *formats, - UINT max_formats, UINT *num_formats, - UINT *num_onscreen_formats) -{ - UINT i; - - if (formats) - { - for (i = 0; i < min(max_formats, nb_formats); ++i) - describe_pixel_format(&pixel_formats[i], &formats[i]); - } - *num_formats = nb_formats; - *num_onscreen_formats = nb_displayable_formats; -} - static const struct opengl_driver_funcs macdrv_driver_funcs = { + .p_init_pixel_formats = macdrv_init_pixel_formats, + .p_describe_pixel_format = macdrv_describe_pixel_format, .p_init_wgl_extensions = macdrv_init_wgl_extensions, .p_set_pixel_format = macdrv_set_pixel_format, }; @@ -3854,5 +3843,4 @@ static struct opengl_funcs opengl_funcs = .p_wglMakeCurrent = macdrv_wglMakeCurrent, .p_wglShareLists = macdrv_wglShareLists, .p_wglSwapBuffers = macdrv_wglSwapBuffers, - .p_get_pixel_formats = macdrv_get_pixel_formats, }; diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index 849a2c3730b..9c4e7234d3d 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -992,13 +992,13 @@ static BOOL wayland_wglSetPbufferAttribARB(struct wgl_pbuffer *pbuffer, const in return GL_TRUE; }
-static void describe_pixel_format(EGLConfig config, struct wgl_pixel_format *fmt, BOOL pbuffer_single) +static BOOL describe_pixel_format(EGLConfig config, struct wgl_pixel_format *fmt, BOOL pbuffer_single) { EGLint value, surface_type; PIXELFORMATDESCRIPTOR *pfd = &fmt->pfd;
/* If we can't get basic information, there is no point continuing */ - if (!p_eglGetConfigAttrib(egl_display, config, EGL_SURFACE_TYPE, &surface_type)) return; + if (!p_eglGetConfigAttrib(egl_display, config, EGL_SURFACE_TYPE, &surface_type)) return FALSE;
memset(fmt, 0, sizeof(*fmt)); pfd->nSize = sizeof(*pfd); @@ -1116,24 +1116,19 @@ static void describe_pixel_format(EGLConfig config, struct wgl_pixel_format *fmt
#undef SET_ATTRIB #undef SET_ATTRIB_ARB + return TRUE; }
-static void wayland_get_pixel_formats(struct wgl_pixel_format *formats, - UINT max_formats, UINT *num_formats, - UINT *num_onscreen_formats) +static BOOL wayland_describe_pixel_format(int format, struct wgl_pixel_format *desc) { - UINT i; - - if (formats) - { - for (i = 0; i < min(max_formats, num_egl_configs); ++i) - describe_pixel_format(egl_configs[i], &formats[i], FALSE); - /* Add single-buffered pbuffer capable configs. */ - for (i = num_egl_configs; i < min(max_formats, 2 * num_egl_configs); ++i) - describe_pixel_format(egl_configs[i - num_egl_configs], &formats[i], TRUE); - } - *num_formats = 2 * num_egl_configs; - *num_onscreen_formats = num_egl_configs; + if (format <= 0) + return FALSE; + if (format <= num_egl_configs) + return describe_pixel_format(egl_configs[format - 1], desc, FALSE); + /* Add single-buffered pbuffer capable configs. */ + if (format <= 2 * num_egl_configs) + return describe_pixel_format(egl_configs[format - 1 - num_egl_configs], desc, TRUE); + return FALSE; }
static BOOL has_extension(const char *list, const char *ext) @@ -1211,7 +1206,7 @@ static const char *wayland_init_wgl_extensions(void) return wgl_extensions; }
-static BOOL init_egl_configs(void) +static UINT wayland_init_pixel_formats(UINT *onscreen_count) { EGLint i; const EGLint attribs[] = @@ -1225,7 +1220,7 @@ static BOOL init_egl_configs(void) if (!(egl_configs = malloc(num_egl_configs * sizeof(*egl_configs)))) { ERR("Failed to allocate memory for EGL configs\n"); - return FALSE; + return 0; } if (!p_eglChooseConfig(egl_display, attribs, egl_configs, num_egl_configs, &num_egl_configs) || @@ -1235,7 +1230,7 @@ static BOOL init_egl_configs(void) egl_configs = NULL; num_egl_configs = 0; ERR("Failed to get any configs from eglChooseConfig\n"); - return FALSE; + return 0; }
if (TRACE_ON(waylanddrv)) @@ -1262,11 +1257,14 @@ static BOOL init_egl_configs(void) } }
- return TRUE; + *onscreen_count = num_egl_configs; + return 2 * num_egl_configs; }
static const struct opengl_driver_funcs wayland_driver_funcs = { + .p_init_pixel_formats = wayland_init_pixel_formats, + .p_describe_pixel_format = wayland_describe_pixel_format, .p_init_wgl_extensions = wayland_init_wgl_extensions, .p_set_pixel_format = wayland_set_pixel_format, }; @@ -1364,7 +1362,6 @@ UINT WAYLAND_OpenGLInit(UINT version, struct opengl_funcs **funcs, const struct has_egl_ext_pixel_format_float = has_extension(egl_exts, "EGL_EXT_pixel_format_float");
if (!init_opengl_funcs()) goto err; - if (!init_egl_configs()) goto err; *funcs = &opengl_funcs; *driver_funcs = &wayland_driver_funcs; return STATUS_SUCCESS; @@ -1384,7 +1381,6 @@ static struct opengl_funcs opengl_funcs = .p_wglMakeCurrent = wayland_wglMakeCurrent, .p_wglShareLists = wayland_wglShareLists, .p_wglSwapBuffers = wayland_wglSwapBuffers, - .p_get_pixel_formats = wayland_get_pixel_formats, };
/********************************************************************** diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index a4c41e1289b..239511b1679 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -280,7 +280,6 @@ static const BOOL is_win64 = sizeof(void *) > sizeof(int);
static struct opengl_funcs opengl_funcs;
-static void init_pixel_formats( Display *display ); static BOOL glxRequireVersion(int requiredVersion);
static void dump_PIXELFORMATDESCRIPTOR(const PIXELFORMATDESCRIPTOR *ppfd) { @@ -713,8 +712,6 @@ UINT X11DRV_OpenGLInit( UINT version, struct opengl_funcs **funcs, const struct pglXSwapBuffersMscOML = pglXGetProcAddressARB( (const GLubyte *)"glXSwapBuffersMscOML" ); }
- init_pixel_formats( gdi_display ); - *funcs = &opengl_funcs; *driver_funcs = &x11drv_driver_funcs; return STATUS_SUCCESS; @@ -773,7 +770,7 @@ static BOOL check_fbconfig_bitmap_capability(Display *display, GLXFBConfig fbcon return !dbuf && (value & GLX_PIXMAP_BIT); }
-static void init_pixel_formats( Display *display ) +static UINT x11drv_init_pixel_formats( UINT *onscreen_count ) { struct glx_pixel_format *list; int size = 0, onscreen_size = 0; @@ -781,11 +778,11 @@ static void init_pixel_formats( Display *display ) GLXFBConfig* cfgs; XVisualInfo *visinfo;
- cfgs = pglXGetFBConfigs(display, DefaultScreen(display), &nCfgs); + cfgs = pglXGetFBConfigs(gdi_display, DefaultScreen(gdi_display), &nCfgs); if (NULL == cfgs || 0 == nCfgs) { if(cfgs != NULL) XFree(cfgs); ERR("glXChooseFBConfig returns NULL\n"); - return; + return 0; }
/* Bitmap rendering on Windows implies the use of the Microsoft GDI software renderer. @@ -797,7 +794,7 @@ static void init_pixel_formats( Display *display ) */ for(i=0, bmp_formats=0; i<nCfgs; i++) { - if(check_fbconfig_bitmap_capability(display, cfgs[i])) + if(check_fbconfig_bitmap_capability(gdi_display, cfgs[i])) bmp_formats++; } TRACE("Found %d bitmap capable fbconfigs\n", bmp_formats); @@ -809,8 +806,8 @@ static void init_pixel_formats( Display *display ) for(run=0; run < 2; run++) { for(i=0; i<nCfgs; i++) { - pglXGetFBConfigAttrib(display, cfgs[i], GLX_FBCONFIG_ID, &fmt_id); - visinfo = pglXGetVisualFromFBConfig(display, cfgs[i]); + pglXGetFBConfigAttrib(gdi_display, cfgs[i], GLX_FBCONFIG_ID, &fmt_id); + visinfo = pglXGetVisualFromFBConfig(gdi_display, cfgs[i]);
/* The first run we only add onscreen formats (ones which have an associated X Visual). * The second run we only set offscreen formats. */ @@ -833,19 +830,19 @@ static void init_pixel_formats( Display *display ) list[size].fbconfig = cfgs[i]; list[size].visual = visinfo; list[size].fmt_id = fmt_id; - list[size].render_type = get_render_type_from_fbconfig(display, cfgs[i]); + list[size].render_type = get_render_type_from_fbconfig(gdi_display, cfgs[i]); list[size].dwFlags = 0; size++; onscreen_size++;
/* Clone a format if it is bitmap capable for indirect rendering to bitmaps */ - if(check_fbconfig_bitmap_capability(display, cfgs[i])) + if(check_fbconfig_bitmap_capability(gdi_display, cfgs[i])) { TRACE("Found bitmap capable format FBCONFIG_ID 0x%x corresponding to iPixelFormat %d at GLX index %d\n", fmt_id, size+1, i); list[size].fbconfig = cfgs[i]; list[size].visual = visinfo; list[size].fmt_id = fmt_id; - list[size].render_type = get_render_type_from_fbconfig(display, cfgs[i]); + list[size].render_type = get_render_type_from_fbconfig(gdi_display, cfgs[i]); list[size].dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI | PFD_GENERIC_FORMAT; size++; onscreen_size++; @@ -869,7 +866,7 @@ static void init_pixel_formats( Display *display ) TRACE("Found offscreen format FBCONFIG_ID 0x%x corresponding to iPixelFormat %d at GLX index %d\n", fmt_id, size+1, i); list[size].fbconfig = cfgs[i]; list[size].fmt_id = fmt_id; - list[size].render_type = get_render_type_from_fbconfig(display, cfgs[i]); + list[size].render_type = get_render_type_from_fbconfig(gdi_display, cfgs[i]); list[size].dwFlags = 0; size++; } @@ -882,6 +879,9 @@ static void init_pixel_formats( Display *display ) pixel_formats = list; nb_pixel_formats = size; nb_onscreen_formats = onscreen_size; + + *onscreen_count = onscreen_size; + return size; }
static inline BOOL is_valid_pixel_format( int format ) @@ -1337,12 +1337,7 @@ void destroy_gl_drawable( HWND hwnd ) }
-/** - * describe_pixel_format - * - * Get the wgl_pixel_format description for the given id - */ -static int describe_pixel_format( int iPixelFormat, struct wgl_pixel_format *pf ) +static BOOL x11drv_describe_pixel_format( int iPixelFormat, struct wgl_pixel_format *pf ) { int value, drawable_type = 0, render_type = 0; int rb, gb, bb, ab; @@ -1355,7 +1350,7 @@ static int describe_pixel_format( int iPixelFormat, struct wgl_pixel_format *pf if (!fmt) { WARN( "unexpected format %d\n", iPixelFormat ); - return 0; + return FALSE; }
/* If we can't get basic information, there is no point continuing */ @@ -1536,7 +1531,7 @@ static int describe_pixel_format( int iPixelFormat, struct wgl_pixel_format *pf
if (TRACE_ON(wgl)) dump_PIXELFORMATDESCRIPTOR( &pf->pfd );
- return nb_onscreen_formats; + return TRUE; }
/*********************************************************************** @@ -2677,23 +2672,10 @@ static BOOL glxdrv_wglSwapBuffers( HDC hdc ) return TRUE; }
-static void glxdrv_get_pixel_formats( struct wgl_pixel_format *formats, - UINT max_formats, UINT *num_formats, - UINT *num_onscreen_formats ) -{ - UINT i; - - if (formats) - { - for (i = 0; i < min( max_formats, nb_pixel_formats ); ++i) - describe_pixel_format( i + 1, &formats[i] ); - } - *num_formats = nb_pixel_formats; - *num_onscreen_formats = nb_onscreen_formats; -} - static const struct opengl_driver_funcs x11drv_driver_funcs = { + .p_init_pixel_formats = x11drv_init_pixel_formats, + .p_describe_pixel_format = x11drv_describe_pixel_format, .p_init_wgl_extensions = x11drv_init_wgl_extensions, .p_set_pixel_format = x11drv_set_pixel_format, }; @@ -2707,7 +2689,6 @@ static struct opengl_funcs opengl_funcs = .p_wglMakeCurrent = glxdrv_wglMakeCurrent, .p_wglShareLists = glxdrv_wglShareLists, .p_wglSwapBuffers = glxdrv_wglSwapBuffers, - .p_get_pixel_formats = glxdrv_get_pixel_formats, };
#else /* no OpenGL includes */ diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index c18edb5476b..f652a58c920 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -113,6 +113,8 @@ struct opengl_funcs /* interface between win32u and the user drivers */ struct opengl_driver_funcs { + UINT (*p_init_pixel_formats)(UINT*); + BOOL (*p_describe_pixel_format)(int,struct wgl_pixel_format*); const char *(*p_init_wgl_extensions)(void); BOOL (*p_set_pixel_format)(HWND,int,int,BOOL); };
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/tests/opengl.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index 387673481e0..120b2b3755d 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -1453,9 +1453,10 @@ static void test_make_current_read(HDC hdc) { int res; HDC hread; - HGLRC hglrc = wglCreateContext(hdc); + HGLRC oldctx, hglrc;
- if(!hglrc) + oldctx = wglGetCurrentContext(); + if(!(hglrc = wglCreateContext(hdc))) { skip("wglCreateContext failed!\n"); return; @@ -1465,6 +1466,7 @@ static void test_make_current_read(HDC hdc) if(!res) { skip("wglMakeCurrent failed!\n"); + wglDeleteContext(hglrc); return; }
@@ -1476,6 +1478,9 @@ static void test_make_current_read(HDC hdc) pwglMakeContextCurrentARB(hdc, hdc, hglrc); hread = pwglGetCurrentReadDCARB(); ok(hread == hdc, "wglGetCurrentReadDCARB failed for wglMakeContextCurrent\n"); + + wglMakeCurrent(hdc, oldctx); + wglDeleteContext(hglrc); }
static void test_dc(HWND hwnd, HDC hdc) @@ -2045,8 +2050,6 @@ static void test_destroy_read(HDC oldhdc) DWORD err; HGLRC oldctx = wglGetCurrentContext();
- ok(!!oldctx, "Expected to find a valid current context\n"); - draw_window = CreateWindowA("static", "opengl32_test", WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0); ok(!!draw_window, "Failed to create window, last error %#lx.\n", GetLastError()); @@ -2203,7 +2206,6 @@ static void test_swap_control(HDC oldhdc) int interval;
oldctx = wglGetCurrentContext(); - ok(!!oldctx, "Expected to find a valid current context.\n");
window1 = CreateWindowA("static", "opengl32_test", WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/tests/opengl.c | 332 +++++++++++++++++++++++++---------- 1 file changed, 244 insertions(+), 88 deletions(-)
diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index 120b2b3755d..fe9e59c092b 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -44,7 +44,6 @@ static HGLRC (WINAPI *pwglCreateContextAttribsARB)(HDC hDC, HGLRC hShareContext,
/* WGL_ARB_extensions_string */ static const char* (WINAPI *pwglGetExtensionsStringARB)(HDC); -static int (WINAPI *pwglReleasePbufferDCARB)(HPBUFFERARB, HDC);
/* WGL_ARB_make_current_read */ static BOOL (WINAPI *pwglMakeContextCurrentARB)(HDC hdraw, HDC hread, HGLRC hglrc); @@ -56,7 +55,10 @@ static BOOL (WINAPI *pwglGetPixelFormatAttribivARB)(HDC, int, int, UINT, const i
/* WGL_ARB_pbuffer */ static HPBUFFERARB (WINAPI *pwglCreatePbufferARB)(HDC, int, int, int, const int *); +static BOOL (WINAPI *pwglDestroyPbufferARB)(HPBUFFERARB); static HDC (WINAPI *pwglGetPbufferDCARB)(HPBUFFERARB); +static int (WINAPI *pwglReleasePbufferDCARB)(HPBUFFERARB, HDC); +static BOOL (WINAPI *pwglQueryPbufferARB)(HPBUFFERARB,int,int*);
/* WGL_EXT_swap_control */ static BOOL (WINAPI *pwglSwapIntervalEXT)(int interval); @@ -113,8 +115,10 @@ static void init_functions(void)
/* WGL_ARB_pbuffer */ GET_PROC(wglCreatePbufferARB) + GET_PROC(wglDestroyPbufferARB) GET_PROC(wglGetPbufferDCARB) GET_PROC(wglReleasePbufferDCARB) + GET_PROC(wglQueryPbufferARB)
/* WGL_EXT_swap_control */ GET_PROC(wglSwapIntervalEXT) @@ -159,104 +163,256 @@ static BOOL gl_extension_supported(const char *extensions, const char *extension return FALSE; }
-static void test_pbuffers(HDC hdc) +static void test_pbuffers( HDC old_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; + int attribs[32] = { WGL_DRAW_TO_PBUFFER_ARB, 1, 0 }; + int formats[MAX_FORMATS], pbuffer_attribs[15] = {0}; + unsigned int i, count, onscreen; + HDC hdc, pbuffer_dc, tmp_dc; + HPBUFFERARB pbuffer; + int res, value; + HGLRC old_rc; + HWND hwnd; + BOOL ret;
- nOnscreenFormats = DescribePixelFormat(hdc, 0, 0, NULL); + old_rc = wglGetCurrentContext();
- /* 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 capabilities. - */ - res = pwglChoosePixelFormatARB(hdc, iAttribList, NULL, MAX_FORMATS, iFormats, &nFormats); - if(res <= 0) + hwnd = CreateWindowW( L"static", NULL, WS_POPUP, 10, 10, 200, 200, NULL, NULL, NULL, NULL ); + ok( !!hwnd, "CreateWindow failed, error %lu\n", GetLastError() ); + hdc = GetDC( hwnd ); + ok( !!hdc, "GetDC failed, error %lu\n", GetLastError() ); + + onscreen = DescribePixelFormat( hdc, 0, 0, NULL ); + attribs[0] = WGL_DRAW_TO_WINDOW_ARB; attribs[1] = 1; + attribs[2] = WGL_COLOR_BITS_ARB; attribs[3] = 32; + attribs[4] = WGL_PIXEL_TYPE_ARB; attribs[5] = WGL_TYPE_RGBA_ARB; + res = pwglChoosePixelFormatARB( hdc, attribs, NULL, MAX_FORMATS, formats, &count ); + ok( res > 0, "got %d\n", res ); + ret = SetPixelFormat( hdc, formats[0], NULL ); + ok( ret == 1, "got %u\n", ret ); + + attribs[0] = WGL_DRAW_TO_PBUFFER_ARB; attribs[1] = 1; + attribs[2] = WGL_COLOR_BITS_ARB; attribs[3] = 32; + attribs[4] = WGL_PIXEL_TYPE_ARB; attribs[5] = WGL_TYPE_RGBA_ARB; + res = pwglChoosePixelFormatARB( hdc, attribs, NULL, MAX_FORMATS, formats, &count ); + ok( res > 0, "got %d\n", res ); + if (count > MAX_FORMATS) count = MAX_FORMATS; + + wglMakeCurrent( 0, 0 ); + + SetLastError( 0xdeadbeef ); + pbuffer = pwglCreatePbufferARB( hdc, 0, 100, 100, pbuffer_attribs ); + ok( !pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); + ok( (GetLastError() & 0xffff) == ERROR_INVALID_PIXEL_FORMAT, "got %lu\n", GetLastError() ); + if (pbuffer) pwglDestroyPbufferARB( pbuffer ); + SetLastError( 0xdeadbeef ); + pbuffer = pwglCreatePbufferARB( hdc, formats[0], 0, 100, pbuffer_attribs ); + todo_wine ok( !pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA, "got %lu\n", GetLastError() ); + if (pbuffer) pwglDestroyPbufferARB( pbuffer ); + if (!winetest_platform_is_wine) /* triggers a BadAlloc */ { - skip("No pbuffer compatible formats found while WGL_ARB_pbuffer is supported\n"); - return; + SetLastError( 0xdeadbeef ); + pbuffer = pwglCreatePbufferARB( hdc, formats[0], -1, 100, pbuffer_attribs ); + ok( !pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); + ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA, "got %lu\n", GetLastError() ); } - 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++) + SetLastError( 0xdeadbeef ); + pbuffer = pwglCreatePbufferARB( hdc, formats[0], 100, 0, pbuffer_attribs ); + todo_wine ok( !pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA, "got %lu\n", GetLastError() ); + if (pbuffer) pwglDestroyPbufferARB( pbuffer ); + if (!winetest_platform_is_wine) /* triggers a BadAlloc */ { - /* 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; - } + SetLastError( 0xdeadbeef ); + pbuffer = pwglCreatePbufferARB( hdc, formats[0], 100, -1, pbuffer_attribs ); + ok( !pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); + ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA, "got %#lx\n", GetLastError() ); } - - /* 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; - int attrib = 0; - HPBUFFERARB pbuffer = pwglCreatePbufferARB(hdc, iPixelFormat, 640 /* width */, 480 /* height */, &attrib); - 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, pbuffer_hdc); + pbuffer = pwglCreatePbufferARB( hdc, formats[0], 100, 100, NULL ); + ok( !!pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); + pwglDestroyPbufferARB( pbuffer ); + + for (i = 0; i < count; i++) + { + winetest_push_context( "%u", formats[i] ); + pbuffer = pwglCreatePbufferARB( hdc, formats[i], 640, 480, pbuffer_attribs ); + ok( !!pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); + pbuffer_dc = pwglGetPbufferDCARB( pbuffer ); + ok( pbuffer_dc != hdc, "got %p\n", pbuffer_dc ); + res = GetPixelFormat( pbuffer_dc ); + ret = pwglReleasePbufferDCARB( pbuffer, pbuffer_dc ); + ok( ret == 1, "got %u\n", ret ); + if (formats[i] > onscreen) ok( res == 1, "got format %d\n", res ); + else ok( res == formats[i] || broken( res == 1 ) /* AMD sometimes */, "got format %d\n", res ); + ret = pwglDestroyPbufferARB( pbuffer ); + ok( ret == 1, "got %u\n", ret ); + winetest_pop_context(); } - 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; - } - } + pbuffer = pwglCreatePbufferARB( hdc, formats[0], 640, 480, pbuffer_attribs ); + ok( !!pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer );
- if(iPixelFormat != 0) - { - HDC pbuffer_hdc; - HPBUFFERARB pbuffer = pwglCreatePbufferARB(hdc, iPixelFormat, 640 /* width */, 480 /* height */, NULL); - if(pbuffer) - { - /* 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 creation failed!\n"); + pbuffer_dc = pwglGetPbufferDCARB( pbuffer ); + ok( pbuffer_dc != hdc, "got %p\n", pbuffer_dc ); + + /* wglGetPbufferDCARB returns the same DC every time */ + tmp_dc = pwglGetPbufferDCARB( pbuffer ); + todo_wine ok( tmp_dc == pbuffer_dc, "got %p\n", tmp_dc ); + + /* releasing the wrong DC returns an error */ + SetLastError( 0xdeadbeef ); + ret = pwglReleasePbufferDCARB( pbuffer, hdc ); + ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_DC_NOT_FOUND, "got %#lx\n", GetLastError() ); + + ret = pwglReleasePbufferDCARB( pbuffer, pbuffer_dc ); + ok( ret == 1, "got %u\n", ret ); + /* releasing the DC more than once may return an error */ + SetLastError( 0xdeadbeef ); + ret = pwglReleasePbufferDCARB( pbuffer, pbuffer_dc ); + todo_wine ok( ret == 1 || broken(ret == 0) /* AMD */, "got %u\n", ret ); + if (!ret) todo_wine ok( (GetLastError() & 0xffff) == ERROR_DC_NOT_FOUND, "got %#lx\n", GetLastError() ); + SetLastError( 0xdeadbeef ); + ret = pwglReleasePbufferDCARB( pbuffer, pbuffer_dc ); + todo_wine ok( ret == 1 || broken(ret == 0) /* AMD */, "got %u\n", ret ); + if (!ret) todo_wine ok( (GetLastError() & 0xffff) == ERROR_DC_NOT_FOUND, "got %#lx\n", GetLastError() ); + + tmp_dc = pwglGetPbufferDCARB( pbuffer ); + if (!ret) ok( tmp_dc != pbuffer_dc, "got %p\n", tmp_dc ); + else todo_wine ok( tmp_dc == pbuffer_dc, "got %p\n", tmp_dc ); + ret = pwglReleasePbufferDCARB( pbuffer, tmp_dc ); + ok( ret == 1, "got %u\n", ret ); + + SetLastError( 0xdeadbeef ); + ret = pwglQueryPbufferARB( NULL, WGL_PBUFFER_WIDTH_ARB, &value ); + ok( ret == 0, "got %u\n", ret ); + ok( (GetLastError() & 0xffff) == ERROR_INVALID_HANDLE, "got %#lx\n", GetLastError() ); + SetLastError( 0xdeadbeef ); + ret = pwglQueryPbufferARB( pbuffer, 0, &value ); + todo_wine ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA, "got %#lx\n", GetLastError() ); + SetLastError( 0xdeadbeef ); + ret = pwglQueryPbufferARB( pbuffer, 0xdeadbeef, &value ); + todo_wine ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA, "got %#lx\n", GetLastError() ); + + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_PBUFFER_WIDTH_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + ok( value == 0 || value == 640, "got %u\n", value ); + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_PBUFFER_HEIGHT_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + ok( value == 0 || value == 480, "got %u\n", value ); + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_PBUFFER_LOST_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + ok( value == 0, "got %u\n", value ); + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_TEXTURE_FORMAT_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + ok( value == WGL_NO_TEXTURE_ARB || broken(value == 0xdeadbeef) /* AMD */, "got %#x\n", value ); + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_TEXTURE_TARGET_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + ok( value == WGL_NO_TEXTURE_ARB || broken(value == 0xdeadbeef) /* AMD */, "got %#x\n", value ); + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_MIPMAP_TEXTURE_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + ok( value == 0 || broken(value > 0) /* AMD */, "got %u\n", value ); + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_MIPMAP_LEVEL_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + todo_wine ok( value == 0 || broken(value > 0) /* AMD */, "got %u\n", value ); + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_CUBE_MAP_FACE_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + todo_wine ok( value == WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB || broken(value == 0xdeadbeef), "got %#x\n", value ); + + SetLastError( 0xdeadbeef ); + ret = pwglDestroyPbufferARB( pbuffer ); + ok( ret == 1, "got %u\n", ret ); + ok( GetLastError() == 0xdeadbeef, "got %#lx\n", GetLastError() ); + /* destroying the pbuffer multiple times is an error */ + SetLastError( 0xdeadbeef ); + ret = pwglDestroyPbufferARB( pbuffer ); + ok( ret == 0, "got %u\n", ret ); + ok( (GetLastError() & 0xffff) == ERROR_INVALID_HANDLE, "got %#lx\n", GetLastError() ); + + if (!winetest_platform_is_wine) /* triggers a BadAlloc */ + { + pbuffer_attribs[0] = WGL_PBUFFER_LARGEST_ARB; + pbuffer_attribs[1] = 1; + pbuffer = pwglCreatePbufferARB( hdc, formats[0], 65535, 65535, pbuffer_attribs ); + ok( !!pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_PBUFFER_WIDTH_ARB, &value ); + ok( ret == 1 || ret == 0, "got %u\n", ret ); + ok( value > 0 && value < 65535, "got %u\n", value ); + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_PBUFFER_HEIGHT_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + ok( value > 0 && value < 65535, "got %u\n", value ); + pwglDestroyPbufferARB( pbuffer ); + + pbuffer_attribs[0] = WGL_PBUFFER_LARGEST_ARB; + pbuffer_attribs[1] = 0; + SetLastError( 0xdeadbeef ); + pbuffer = pwglCreatePbufferARB( hdc, formats[0], 65535, 65535, pbuffer_attribs ); + ok( !pbuffer || broken(!!pbuffer) /* AMD */, "wglCreatePbufferARB returned %p\n", pbuffer ); + ok( (GetLastError() & 0xffff) == ERROR_NO_SYSTEM_RESOURCES || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + if (pbuffer) pwglDestroyPbufferARB( pbuffer ); } - else skip("Pbuffer test for offscreen pixelformat skipped as no offscreen-only format with pbuffer capabilities has been found\n"); + + pbuffer_attribs[0] = WGL_TEXTURE_FORMAT_ARB; + pbuffer_attribs[1] = WGL_TEXTURE_RGB_ARB; + pbuffer_attribs[2] = WGL_TEXTURE_TARGET_ARB; + pbuffer_attribs[3] = WGL_TEXTURE_CUBE_MAP_ARB; + pbuffer_attribs[4] = WGL_MIPMAP_TEXTURE_ARB; + pbuffer_attribs[5] = 4; + pbuffer = pwglCreatePbufferARB( hdc, formats[0], 512, 512, pbuffer_attribs ); + ok( !!pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); + + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_PBUFFER_WIDTH_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + ok( value == 512 || broken(value == 0) /* AMD */, "got %u\n", value ); + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_PBUFFER_HEIGHT_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + ok( value == 512 || broken(value == 0) /* AMD */, "got %u\n", value ); + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_PBUFFER_LOST_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + ok( value == 0, "got %u\n", value ); + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_TEXTURE_FORMAT_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + ok( value == WGL_TEXTURE_RGB_ARB || broken(value == 0xdeadbeef) /* AMD */, "got %#x\n", value ); + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_TEXTURE_TARGET_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + ok( value == WGL_TEXTURE_CUBE_MAP_ARB || broken(value == 0xdeadbeef) /* AMD */, "got %#x\n", value ); + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_MIPMAP_TEXTURE_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + todo_wine ok( value == 1 || broken(value > 0) /* AMD */, "got %u\n", value ); + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_MIPMAP_LEVEL_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + todo_wine ok( value == 0 || broken(value > 0) /* AMD */, "got %u\n", value ); + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_CUBE_MAP_FACE_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + todo_wine ok( value == WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB || broken(value == 0xdeadbeef) /* AMD */, "got %#x\n", value ); + + pwglDestroyPbufferARB( pbuffer ); + + ReleaseDC( hwnd, hdc ); + DestroyWindow( hwnd ); + + wglMakeCurrent( old_hdc, old_rc ); }
static int test_pfd(const PIXELFORMATDESCRIPTOR *pfd, PIXELFORMATDESCRIPTOR *fmt)
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/tests/opengl.c | 320 ++++++++++++++++++++++++++++++++++- 1 file changed, 319 insertions(+), 1 deletion(-)
diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index fe9e59c092b..9500b300f18 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -60,6 +60,11 @@ static HDC (WINAPI *pwglGetPbufferDCARB)(HPBUFFERARB); static int (WINAPI *pwglReleasePbufferDCARB)(HPBUFFERARB, HDC); static BOOL (WINAPI *pwglQueryPbufferARB)(HPBUFFERARB,int,int*);
+/* WGL_ARB_render_texture */ +static BOOL (WINAPI *pwglBindTexImageARB)(HPBUFFERARB,int); +static BOOL (WINAPI *pwglReleaseTexImageARB)(HPBUFFERARB,int); +static BOOL (WINAPI *pwglSetPbufferAttribARB)(HPBUFFERARB,const int*); + /* WGL_EXT_swap_control */ static BOOL (WINAPI *pwglSwapIntervalEXT)(int interval); static int (WINAPI *pwglGetSwapIntervalEXT)(void); @@ -120,6 +125,11 @@ static void init_functions(void) GET_PROC(wglReleasePbufferDCARB) GET_PROC(wglQueryPbufferARB)
+ /* WGL_ARB_render_texture */ + GET_PROC(wglBindTexImageARB) + GET_PROC(wglReleaseTexImageARB) + GET_PROC(wglSetPbufferAttribARB) + /* WGL_EXT_swap_control */ GET_PROC(wglSwapIntervalEXT) GET_PROC(wglGetSwapIntervalEXT) @@ -168,10 +178,12 @@ static void test_pbuffers( HDC old_hdc ) int attribs[32] = { WGL_DRAW_TO_PBUFFER_ARB, 1, 0 }; int formats[MAX_FORMATS], pbuffer_attribs[15] = {0}; unsigned int i, count, onscreen; + unsigned int pixels[16 * 16]; HDC hdc, pbuffer_dc, tmp_dc; HPBUFFERARB pbuffer; + HGLRC rc, old_rc; int res, value; - HGLRC old_rc; + GLuint texture; HWND hwnd; BOOL ret;
@@ -330,6 +342,53 @@ static void test_pbuffers( HDC old_hdc ) ok( ret == 1, "got %u\n", ret ); todo_wine ok( value == WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB || broken(value == 0xdeadbeef), "got %#x\n", value );
+ pbuffer_attribs[0] = WGL_PBUFFER_WIDTH_ARB; + pbuffer_attribs[1] = 50; + SetLastError( 0xdeadbeef ); + ret = pwglSetPbufferAttribARB( pbuffer, pbuffer_attribs ); + ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + pbuffer_attribs[0] = WGL_PBUFFER_HEIGHT_ARB; + pbuffer_attribs[1] = 50; + SetLastError( 0xdeadbeef ); + ret = pwglSetPbufferAttribARB( pbuffer, pbuffer_attribs ); + ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + pbuffer_attribs[0] = WGL_PBUFFER_LOST_ARB; + pbuffer_attribs[1] = 0; + SetLastError( 0xdeadbeef ); + ret = pwglSetPbufferAttribARB( pbuffer, pbuffer_attribs ); + ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + pbuffer_attribs[0] = WGL_TEXTURE_FORMAT_ARB; + pbuffer_attribs[1] = WGL_TEXTURE_RGBA_ARB; + SetLastError( 0xdeadbeef ); + ret = pwglSetPbufferAttribARB( pbuffer, pbuffer_attribs ); + ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + pbuffer_attribs[0] = WGL_TEXTURE_TARGET_ARB; + pbuffer_attribs[1] = WGL_TEXTURE_2D_ARB; + SetLastError( 0xdeadbeef ); + ret = pwglSetPbufferAttribARB( pbuffer, pbuffer_attribs ); + ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + pbuffer_attribs[0] = WGL_MIPMAP_TEXTURE_ARB; + pbuffer_attribs[1] = 1; + SetLastError( 0xdeadbeef ); + ret = pwglSetPbufferAttribARB( pbuffer, pbuffer_attribs ); + ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + pbuffer_attribs[0] = WGL_MIPMAP_LEVEL_ARB; + pbuffer_attribs[1] = 1; + SetLastError( 0xdeadbeef ); + ret = pwglSetPbufferAttribARB( pbuffer, pbuffer_attribs ); + ok( ret == 0 || broken(ret == 1) /* AMD */, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + pbuffer_attribs[0] = WGL_CUBE_MAP_FACE_ARB; + pbuffer_attribs[1] = WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB; + ret = pwglSetPbufferAttribARB( pbuffer, pbuffer_attribs ); + todo_wine ok( ret == 1, "got %u\n", ret ); + SetLastError( 0xdeadbeef ); ret = pwglDestroyPbufferARB( pbuffer ); ok( ret == 1, "got %u\n", ret ); @@ -407,6 +466,265 @@ static void test_pbuffers( HDC old_hdc ) ok( ret == 1, "got %u\n", ret ); todo_wine ok( value == WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB || broken(value == 0xdeadbeef) /* AMD */, "got %#x\n", value );
+ pbuffer_attribs[0] = WGL_PBUFFER_WIDTH_ARB; + pbuffer_attribs[1] = 50; + SetLastError( 0xdeadbeef ); + ret = pwglSetPbufferAttribARB( pbuffer, pbuffer_attribs ); + todo_wine ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + pbuffer_attribs[0] = WGL_PBUFFER_HEIGHT_ARB; + pbuffer_attribs[1] = 50; + SetLastError( 0xdeadbeef ); + ret = pwglSetPbufferAttribARB( pbuffer, pbuffer_attribs ); + todo_wine ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + pbuffer_attribs[0] = WGL_PBUFFER_LOST_ARB; + pbuffer_attribs[1] = 0; + SetLastError( 0xdeadbeef ); + ret = pwglSetPbufferAttribARB( pbuffer, pbuffer_attribs ); + todo_wine ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + pbuffer_attribs[0] = WGL_TEXTURE_FORMAT_ARB; + pbuffer_attribs[1] = WGL_TEXTURE_RGBA_ARB; + SetLastError( 0xdeadbeef ); + ret = pwglSetPbufferAttribARB( pbuffer, pbuffer_attribs ); + todo_wine ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + pbuffer_attribs[0] = WGL_TEXTURE_TARGET_ARB; + pbuffer_attribs[1] = WGL_TEXTURE_2D_ARB; + SetLastError( 0xdeadbeef ); + ret = pwglSetPbufferAttribARB( pbuffer, pbuffer_attribs ); + todo_wine ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + pbuffer_attribs[0] = WGL_MIPMAP_TEXTURE_ARB; + pbuffer_attribs[1] = 2; + SetLastError( 0xdeadbeef ); + ret = pwglSetPbufferAttribARB( pbuffer, pbuffer_attribs ); + todo_wine ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + pbuffer_attribs[0] = WGL_MIPMAP_LEVEL_ARB; + pbuffer_attribs[1] = 2; + SetLastError( 0xdeadbeef ); + ret = pwglSetPbufferAttribARB( pbuffer, pbuffer_attribs ); + todo_wine ok( ret == 0 || broken(ret == 1) /* AMD */, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + pbuffer_attribs[0] = WGL_CUBE_MAP_FACE_ARB; + pbuffer_attribs[1] = WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB; + SetLastError( 0xdeadbeef ); + ret = pwglSetPbufferAttribARB( pbuffer, pbuffer_attribs ); + todo_wine ok( ret == 0 || broken(ret == 1) /* AMD */, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_PBUFFER_WIDTH_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + ok( value == 512 || broken(value == 0) /* AMD */, "got %u\n", value ); + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_PBUFFER_HEIGHT_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + ok( value == 512 || broken(value == 0) /* AMD */, "got %u\n", value ); + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_PBUFFER_LOST_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + ok( value == 0, "got %u\n", value ); + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_TEXTURE_FORMAT_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + ok( value == WGL_TEXTURE_RGB_ARB || broken(value == 0xdeadbeef) /* AMD */, "got %#x\n", value ); + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_TEXTURE_TARGET_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + ok( value == WGL_TEXTURE_CUBE_MAP_ARB || broken(value == 0xdeadbeef) /* AMD */, "got %#x\n", value ); + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_MIPMAP_TEXTURE_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + todo_wine ok( value == 1 || broken(value > 0) /* AMD */, "got %u\n", value ); + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_MIPMAP_LEVEL_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + todo_wine ok( value == 0 || broken(value > 0) /* AMD */, "got %u\n", value ); + value = 0xdeadbeef; + ret = pwglQueryPbufferARB( pbuffer, WGL_CUBE_MAP_FACE_ARB, &value ); + ok( ret == 1, "got %u\n", ret ); + todo_wine ok( value == WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB || broken(value == 0xdeadbeef) /* AMD */, "got %#x\n", value ); + + pwglDestroyPbufferARB( pbuffer ); + + + pbuffer_attribs[0] = WGL_TEXTURE_FORMAT_ARB; + pbuffer_attribs[1] = WGL_TEXTURE_RGB_ARB; + pbuffer_attribs[2] = WGL_TEXTURE_TARGET_ARB; + pbuffer_attribs[3] = WGL_TEXTURE_2D_ARB; + pbuffer_attribs[4] = 0; + pbuffer = pwglCreatePbufferARB( hdc, formats[0], 16, 16, pbuffer_attribs ); + ok( !!pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); + + pbuffer_dc = pwglGetPbufferDCARB( pbuffer ); + ok( !!pbuffer_dc, "got %p\n", pbuffer_dc ); + rc = wglCreateContext( pbuffer_dc ); + ok( !!rc, "got %p\n", rc ); + ret = wglMakeCurrent( pbuffer_dc, rc ); + ok( ret == 1, "got %u\n", ret ); + + if (!winetest_platform_is_wine) /* triggers a BadMatch */ + { + glClearColor( (float)0x22 / 0xff, (float)0x33 / 0xff, (float)0x44 / 0xff, (float)0x11 / 0xff ); + glClear( GL_COLOR_BUFFER_BIT ); + } + + ret = wglMakeCurrent( 0, 0 ); + ok( ret == 1, "got %u\n", ret ); + ret = wglDeleteContext( rc ); + ok( ret == 1, "got %u\n", ret ); + ret = pwglReleasePbufferDCARB( pbuffer, pbuffer_dc ); + ok( ret == 1, "got %u\n", ret ); + + + rc = wglCreateContext( hdc ); + ok( !!rc, "got %p\n", rc ); + ret = wglMakeCurrent( hdc, rc ); + ok( ret == 1, "got %u\n", ret ); + + /* test some invalid params */ + SetLastError( 0xdeadbeef ); + ret = pwglReleaseTexImageARB( pbuffer, GL_FRONT ); + todo_wine ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(GetLastError() == 0xdeadbeef) /* AMD */, "got %#lx\n", GetLastError() ); + SetLastError( 0xdeadbeef ); + ret = pwglBindTexImageARB( pbuffer, GL_BACK ); + todo_wine ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(GetLastError() == 0xdeadbeef) /* AMD */, "got %#lx\n", GetLastError() ); + + /* test invalid calls */ + SetLastError( 0xdeadbeef ); + ret = pwglReleaseTexImageARB( pbuffer, WGL_BACK_LEFT_ARB ); + todo_wine ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + + value = 0xdeadbeef; + glGetIntegerv( GL_TEXTURE_BINDING_2D, &value ); + ok( value == 0, "got %u\n", value ); + value = 0xdeadbeef; + glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &value ); + todo_wine ok( value == 0, "got %u\n", value ); + value = 0xdeadbeef; + glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &value ); + todo_wine ok( value == 0, "got %u\n", value ); + memset( pixels, 0xcd, sizeof(pixels) ); + glGetTexImage( GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels ); + todo_wine ok( pixels[0] == 0xcdcdcdcd, "got %#x\n", pixels[0] ); + ret = pwglReleaseTexImageARB( pbuffer, WGL_FRONT_LEFT_ARB ); + ok( ret == 1 || broken(ret == 0) /* AMD */, "got %u\n", ret ); + + ret = pwglBindTexImageARB( pbuffer, WGL_FRONT_LEFT_ARB ); + ok( ret == 1 || broken(ret == 0) /* AMD */, "got %u\n", ret ); + + value = 0xdeadbeef; + glGetIntegerv( GL_TEXTURE_BINDING_2D, &value ); + ok( value == 0, "got %u\n", value ); + value = 0xdeadbeef; + glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &value ); + ok( value == 16 || broken(value == 0) /* AMD */, "got %u\n", value ); + value = 0xdeadbeef; + glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &value ); + ok( value == 16 || broken(value == 0) /* AMD */, "got %u\n", value ); + memset( pixels, 0xcd, sizeof(pixels) ); + glGetTexImage( GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels ); + todo_wine ok( (pixels[0] & 0xffffff) == 0x443322 || broken(pixels[0] == 0xcdcdcdcd) /* AMD */, "got %#x\n", pixels[0] ); + + SetLastError( 0xdeadbeef ); + ret = pwglBindTexImageARB( pbuffer, WGL_FRONT_LEFT_ARB ); + todo_wine ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + SetLastError( 0xdeadbeef ); + ret = pwglBindTexImageARB( pbuffer, WGL_FRONT_RIGHT_ARB ); + todo_wine ok( ret == 0, "got %u\n", ret ); + todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + + pwglReleaseTexImageARB( pbuffer, WGL_FRONT_LEFT_ARB ); + ret = pwglReleaseTexImageARB( pbuffer, WGL_FRONT_LEFT_ARB ); + ok( ret == 1 || broken(ret == 0) /* AMD */, "got %u\n", ret ); + + glGenTextures( 1, &texture ); + glEnable( GL_TEXTURE_2D ); + glBindTexture( GL_TEXTURE_2D, texture ); + memset( pixels, 0xa5, sizeof(pixels) ); + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels ); + + value = 0xdeadbeef; + glGetIntegerv( GL_TEXTURE_BINDING_2D, &value ); + ok( value == texture, "got %u\n", value ); + value = 0xdeadbeef; + glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &value ); + ok( value == 8, "got %u\n", value ); + value = 0xdeadbeef; + glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &value ); + ok( value == 8, "got %u\n", value ); + memset( pixels, 0xcd, sizeof(pixels) ); + glGetTexImage( GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels ); + ok( (pixels[0] & 0xffffff) == 0xa5a5a5, "got %#x\n", pixels[0] ); + + ret = pwglBindTexImageARB( pbuffer, WGL_FRONT_LEFT_ARB ); + ok( ret == 1 || broken(ret == 0) /* AMD */, "got %u\n", ret ); + + value = 0xdeadbeef; + glGetIntegerv( GL_TEXTURE_BINDING_2D, &value ); + ok( value == texture, "got %u\n", value ); + value = 0xdeadbeef; + glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &value ); + ok( value == 16 || broken(value == 8) /* AMD */, "got %u\n", value ); + value = 0xdeadbeef; + glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &value ); + ok( value == 16 || broken(value == 8) /* AMD */, "got %u\n", value ); + memset( pixels, 0xcd, sizeof(pixels) ); + glGetTexImage( GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels ); + todo_wine ok( (pixels[0] & 0xffffff) == 0x443322 || broken(pixels[0] == 0xa5a5a5a5) /* AMD */, "got %#x\n", pixels[0] ); + + ret = pwglReleaseTexImageARB( pbuffer, WGL_FRONT_LEFT_ARB ); + ok( ret == 1 || broken(ret == 0) /* AMD */, "got %u\n", ret ); + + value = 0xdeadbeef; + glGetIntegerv( GL_TEXTURE_BINDING_2D, &value ); + ok( value == texture, "got %u\n", value ); + value = 0xdeadbeef; + glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &value ); + todo_wine ok( value == 0 || broken(value == 8) /* AMD */, "got %u\n", value ); + value = 0xdeadbeef; + glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &value ); + todo_wine ok( value == 0 || broken(value == 8) /* AMD */, "got %u\n", value ); + memset( pixels, 0xcd, sizeof(pixels) ); + glGetTexImage( GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels ); + todo_wine ok( pixels[0] == 0xcdcdcdcd || broken(pixels[0] == 0xa5a5a5a5) /* AMD */, "got %#x\n", pixels[0] ); + + ret = pwglReleaseTexImageARB( pbuffer, WGL_FRONT_LEFT_ARB ); + ok( ret == 1 || broken(ret == 0) /* AMD */, "got %u\n", ret ); + ret = pwglReleaseTexImageARB( pbuffer, WGL_FRONT_LEFT_ARB ); + ok( ret == 1 || broken(ret == 0) /* AMD */, "got %u\n", ret ); + + ret = pwglBindTexImageARB( pbuffer, WGL_FRONT_RIGHT_ARB ); + ok( ret == 1 || broken(ret == 0) /* AMD */, "got %u\n", ret ); + + value = 0xdeadbeef; + glGetIntegerv( GL_TEXTURE_BINDING_2D, &value ); + ok( value == texture, "got %u\n", value ); + value = 0xdeadbeef; + glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &value ); + todo_wine ok( value == 0 || broken(value == 8) /* AMD */, "got %u\n", value ); + value = 0xdeadbeef; + glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &value ); + todo_wine ok( value == 0 || broken(value == 8) /* AMD */, "got %u\n", value ); + memset( pixels, 0xcd, sizeof(pixels) ); + glGetTexImage( GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels ); + todo_wine ok( pixels[0] == 0xcdcdcdcd || broken(pixels[0] == 0xa5a5a5a5) /* AMD */, "got %#x\n", pixels[0] ); + + ret = pwglReleaseTexImageARB( pbuffer, WGL_FRONT_RIGHT_ARB ); + ok( ret == 1 || broken(ret == 0) /* AMD */, "got %u\n", ret ); + + glDeleteTextures( 1, &texture ); + + ret = wglDeleteContext( rc ); + ok( ret == 1, "got %u\n", ret ); + pwglDestroyPbufferARB( pbuffer );
ReleaseDC( hwnd, hdc );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/tests/opengl.c | 24 +- dlls/win32u/opengl.c | 315 +++++++++++++++++++++++++ dlls/winex11.drv/opengl.c | 445 +++-------------------------------- include/wine/opengl_driver.h | 3 + 4 files changed, 361 insertions(+), 426 deletions(-)
diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index 9500b300f18..c1fe8ac1245 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -219,28 +219,22 @@ static void test_pbuffers( HDC old_hdc ) if (pbuffer) pwglDestroyPbufferARB( pbuffer ); SetLastError( 0xdeadbeef ); pbuffer = pwglCreatePbufferARB( hdc, formats[0], 0, 100, pbuffer_attribs ); - todo_wine ok( !pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); - todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA, "got %lu\n", GetLastError() ); + ok( !pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); + ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA, "got %lu\n", GetLastError() ); if (pbuffer) pwglDestroyPbufferARB( pbuffer ); - if (!winetest_platform_is_wine) /* triggers a BadAlloc */ - { SetLastError( 0xdeadbeef ); pbuffer = pwglCreatePbufferARB( hdc, formats[0], -1, 100, pbuffer_attribs ); ok( !pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA, "got %lu\n", GetLastError() ); - } SetLastError( 0xdeadbeef ); pbuffer = pwglCreatePbufferARB( hdc, formats[0], 100, 0, pbuffer_attribs ); - todo_wine ok( !pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); - todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA, "got %lu\n", GetLastError() ); + ok( !pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); + ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA, "got %lu\n", GetLastError() ); if (pbuffer) pwglDestroyPbufferARB( pbuffer ); - if (!winetest_platform_is_wine) /* triggers a BadAlloc */ - { SetLastError( 0xdeadbeef ); pbuffer = pwglCreatePbufferARB( hdc, formats[0], 100, -1, pbuffer_attribs ); ok( !pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA, "got %#lx\n", GetLastError() ); - } pbuffer = pwglCreatePbufferARB( hdc, formats[0], 100, 100, NULL ); ok( !!pbuffer, "wglCreatePbufferARB returned %p\n", pbuffer ); pwglDestroyPbufferARB( pbuffer ); @@ -270,29 +264,29 @@ static void test_pbuffers( HDC old_hdc )
/* wglGetPbufferDCARB returns the same DC every time */ tmp_dc = pwglGetPbufferDCARB( pbuffer ); - todo_wine ok( tmp_dc == pbuffer_dc, "got %p\n", tmp_dc ); + ok( tmp_dc == pbuffer_dc, "got %p\n", tmp_dc );
/* releasing the wrong DC returns an error */ SetLastError( 0xdeadbeef ); ret = pwglReleasePbufferDCARB( pbuffer, hdc ); ok( ret == 0, "got %u\n", ret ); - todo_wine ok( (GetLastError() & 0xffff) == ERROR_DC_NOT_FOUND, "got %#lx\n", GetLastError() ); + ok( (GetLastError() & 0xffff) == ERROR_DC_NOT_FOUND, "got %#lx\n", GetLastError() );
ret = pwglReleasePbufferDCARB( pbuffer, pbuffer_dc ); ok( ret == 1, "got %u\n", ret ); /* releasing the DC more than once may return an error */ SetLastError( 0xdeadbeef ); ret = pwglReleasePbufferDCARB( pbuffer, pbuffer_dc ); - todo_wine ok( ret == 1 || broken(ret == 0) /* AMD */, "got %u\n", ret ); + ok( ret == 1 || broken(ret == 0) /* AMD */, "got %u\n", ret ); if (!ret) todo_wine ok( (GetLastError() & 0xffff) == ERROR_DC_NOT_FOUND, "got %#lx\n", GetLastError() ); SetLastError( 0xdeadbeef ); ret = pwglReleasePbufferDCARB( pbuffer, pbuffer_dc ); - todo_wine ok( ret == 1 || broken(ret == 0) /* AMD */, "got %u\n", ret ); + ok( ret == 1 || broken(ret == 0) /* AMD */, "got %u\n", ret ); if (!ret) todo_wine ok( (GetLastError() & 0xffff) == ERROR_DC_NOT_FOUND, "got %#lx\n", GetLastError() );
tmp_dc = pwglGetPbufferDCARB( pbuffer ); if (!ret) ok( tmp_dc != pbuffer_dc, "got %p\n", tmp_dc ); - else todo_wine ok( tmp_dc == pbuffer_dc, "got %p\n", tmp_dc ); + else ok( tmp_dc == pbuffer_dc, "got %p\n", tmp_dc ); ret = pwglReleasePbufferDCARB( pbuffer, tmp_dc ); ok( ret == 1, "got %u\n", ret );
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 9686f64ab2b..3498a693b2b 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -39,6 +39,22 @@
WINE_DEFAULT_DEBUG_CHANNEL(wgl);
+struct wgl_pbuffer +{ + const struct opengl_driver_funcs *driver_funcs; + struct opengl_funcs *funcs; + void *driver_private; + + HDC hdc; + GLsizei width; + GLsizei height; + GLenum texture_format; + GLenum texture_target; + + struct wgl_context *tmp_context; + struct wgl_context *prev_context; +}; + static struct opengl_funcs *get_dc_funcs( HDC hdc, void *null_funcs );
static const struct @@ -502,6 +518,290 @@ static void win32u_get_pixel_formats( struct wgl_pixel_format *formats, UINT max *num_onscreen_formats = onscreen_count; }
+static struct wgl_pbuffer *win32u_wglCreatePbufferARB( HDC hdc, int format, int width, int height, + const int *attribs ) +{ + struct wgl_pbuffer *pbuffer; + struct opengl_funcs *funcs; + UINT total, onscreen; + BOOL largest = FALSE; + + TRACE( "(%p, %d, %d, %d, %p)\n", hdc, format, width, height, attribs ); + + if (!(funcs = get_dc_funcs( hdc, NULL ))) return FALSE; + funcs->p_get_pixel_formats( NULL, 0, &total, &onscreen ); + if (format <= 0 || format > total) + { + RtlSetLastWin32Error( ERROR_INVALID_PIXEL_FORMAT ); + return NULL; + } + if (width <= 0 || height <= 0) + { + RtlSetLastWin32Error( ERROR_INVALID_DATA ); + return NULL; + } + + if (!(pbuffer = calloc( 1, sizeof(*pbuffer) )) || !(pbuffer->hdc = NtGdiOpenDCW( NULL, NULL, NULL, 0, TRUE, NULL, NULL, NULL ))) + { + RtlSetLastWin32Error( ERROR_NO_SYSTEM_RESOURCES ); + free( pbuffer ); + return NULL; + } + NtGdiSetPixelFormat( pbuffer->hdc, format ); + pbuffer->driver_funcs = driver_funcs; + pbuffer->funcs = funcs; + pbuffer->width = width; + pbuffer->height = height; + + for (; attribs && attribs[0]; attribs += 2) + { + switch (attribs[0]) + { + case WGL_PBUFFER_LARGEST_ARB: + TRACE( "WGL_PBUFFER_LARGEST_ARB %#x\n", attribs[1] ); + largest = !!attribs[1]; + break; + + case WGL_TEXTURE_FORMAT_ARB: + TRACE( "WGL_TEXTURE_FORMAT_ARB %#x\n", attribs[1] ); + switch (attribs[1]) + { + case WGL_NO_TEXTURE_ARB: + pbuffer->texture_format = 0; + break; + case WGL_TEXTURE_RGB_ARB: + pbuffer->texture_format = GL_RGB; + break; + case WGL_TEXTURE_RGBA_ARB: + pbuffer->texture_format = GL_RGBA; + break; + /* WGL_FLOAT_COMPONENTS_NV */ + case WGL_TEXTURE_FLOAT_R_NV: + pbuffer->texture_format = GL_FLOAT_R_NV; + break; + case WGL_TEXTURE_FLOAT_RG_NV: + pbuffer->texture_format = GL_FLOAT_RG_NV; + break; + case WGL_TEXTURE_FLOAT_RGB_NV: + pbuffer->texture_format = GL_FLOAT_RGB_NV; + break; + case WGL_TEXTURE_FLOAT_RGBA_NV: + pbuffer->texture_format = GL_FLOAT_RGBA_NV; + break; + default: + FIXME( "Unknown texture format: %x\n", attribs[1] ); + goto failed; + } + break; + + case WGL_TEXTURE_TARGET_ARB: + TRACE( "WGL_TEXTURE_TARGET_ARB %#x\n", attribs[1] ); + switch (attribs[1]) + { + case WGL_NO_TEXTURE_ARB: + pbuffer->texture_target = 0; + break; + case WGL_TEXTURE_CUBE_MAP_ARB: + if (width != height) goto failed; + pbuffer->texture_target = GL_TEXTURE_CUBE_MAP; + break; + case WGL_TEXTURE_1D_ARB: + if (height != 1) goto failed; + pbuffer->texture_target = GL_TEXTURE_1D; + break; + case WGL_TEXTURE_2D_ARB: + pbuffer->texture_target = GL_TEXTURE_2D; + break; + case WGL_TEXTURE_RECTANGLE_NV: + pbuffer->texture_target = GL_TEXTURE_RECTANGLE_NV; + break; + default: + FIXME( "Unknown texture target: %x\n", attribs[1] ); + goto failed; + } + break; + + case WGL_MIPMAP_TEXTURE_ARB: + TRACE( "WGL_MIPMAP_TEXTURE_ARB %#x\n", attribs[1] ); + break; + + default: + WARN( "attribute %#x %#x not handled\n", attribs[0], attribs[1] ); + break; + } + } + + if (pbuffer->driver_funcs->p_pbuffer_create( pbuffer->hdc, format, largest, &pbuffer->width, + &pbuffer->height, &pbuffer->driver_private )) + return pbuffer; + +failed: + RtlSetLastWin32Error( ERROR_INVALID_DATA ); + NtGdiDeleteObjectApp( pbuffer->hdc ); + free( pbuffer ); + return NULL; +} + +static BOOL win32u_wglDestroyPbufferARB( struct wgl_pbuffer *pbuffer ) +{ + TRACE( "pbuffer %p\n", pbuffer ); + + pbuffer->driver_funcs->p_pbuffer_destroy( pbuffer->hdc, pbuffer->driver_private ); + if (pbuffer->tmp_context) pbuffer->funcs->p_wglDeleteContext( pbuffer->tmp_context ); + NtGdiDeleteObjectApp( pbuffer->hdc ); + free( pbuffer ); + + return GL_TRUE; +} + +static HDC win32u_wglGetPbufferDCARB( struct wgl_pbuffer *pbuffer ) +{ + TRACE( "pbuffer %p\n", pbuffer ); + return pbuffer->hdc; +} + +static int win32u_wglReleasePbufferDCARB( struct wgl_pbuffer *pbuffer, HDC hdc ) +{ + TRACE( "pbuffer %p, hdc %p\n", pbuffer, hdc ); + + if (hdc != pbuffer->hdc) + { + RtlSetLastWin32Error( ERROR_DC_NOT_FOUND ); + return FALSE; + } + + return TRUE; +} + +static BOOL win32u_wglQueryPbufferARB( struct wgl_pbuffer *pbuffer, int attrib, int *value ) +{ + TRACE( "pbuffer %p, attrib %#x, value %p\n", pbuffer, attrib, value ); + + switch (attrib) + { + case WGL_PBUFFER_WIDTH_ARB: + *value = pbuffer->width; + break; + case WGL_PBUFFER_HEIGHT_ARB: + *value = pbuffer->height; + break; + case WGL_PBUFFER_LOST_ARB: + *value = GL_FALSE; + break; + + case WGL_TEXTURE_FORMAT_ARB: + switch (pbuffer->texture_format) + { + case 0: *value = WGL_NO_TEXTURE_ARB; break; + case GL_RGB: *value = WGL_TEXTURE_RGB_ARB; break; + case GL_RGBA: *value = WGL_TEXTURE_RGBA_ARB; break; + /* WGL_FLOAT_COMPONENTS_NV */ + case GL_FLOAT_R_NV: *value = WGL_TEXTURE_FLOAT_R_NV; break; + case GL_FLOAT_RG_NV: *value = WGL_TEXTURE_FLOAT_RG_NV; break; + case GL_FLOAT_RGB_NV: *value = WGL_TEXTURE_FLOAT_RGB_NV; break; + case GL_FLOAT_RGBA_NV: *value = WGL_TEXTURE_FLOAT_RGBA_NV; break; + default: ERR( "Unknown texture format: %x\n", pbuffer->texture_format ); + } + break; + + case WGL_TEXTURE_TARGET_ARB: + switch (pbuffer->texture_target) + { + case 0: *value = WGL_NO_TEXTURE_ARB; break; + case GL_TEXTURE_1D: *value = WGL_TEXTURE_1D_ARB; break; + case GL_TEXTURE_2D: *value = WGL_TEXTURE_2D_ARB; break; + case GL_TEXTURE_CUBE_MAP: *value = WGL_TEXTURE_CUBE_MAP_ARB; break; + case GL_TEXTURE_RECTANGLE_NV: *value = WGL_TEXTURE_RECTANGLE_NV; break; + } + break; + + case WGL_MIPMAP_TEXTURE_ARB: + *value = GL_FALSE; + FIXME( "WGL_MIPMAP_TEXTURE_ARB not supported\n" ); + break; + + default: + FIXME( "unexpected attribute %x\n", attrib ); + break; + } + + return GL_TRUE; +} + +static GLenum binding_from_target( GLenum target ) +{ + switch (target) + { + case GL_TEXTURE_CUBE_MAP: return GL_TEXTURE_BINDING_CUBE_MAP; + case GL_TEXTURE_1D: return GL_TEXTURE_BINDING_1D; + case GL_TEXTURE_2D: return GL_TEXTURE_BINDING_2D; + case GL_TEXTURE_RECTANGLE_NV: return GL_TEXTURE_BINDING_RECTANGLE_NV; + } + FIXME( "Unsupported target %#x\n", target ); + return 0; +} + +static BOOL win32u_wglBindTexImageARB( struct wgl_pbuffer *pbuffer, int buffer ) +{ + HDC prev_draw = NtCurrentTeb()->glReserved1[0], prev_read = NtCurrentTeb()->glReserved1[1]; + struct wgl_context *prev_context = NtCurrentTeb()->glContext; + int prev_texture = 0; + + TRACE( "pbuffer %p, buffer %d\n", pbuffer, buffer ); + + if (!pbuffer->texture_format) + { + RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); + return GL_FALSE; + } + + if (!pbuffer->tmp_context || pbuffer->prev_context != prev_context) + { + if (pbuffer->tmp_context) pbuffer->funcs->p_wglDeleteContext( pbuffer->tmp_context ); + pbuffer->tmp_context = pbuffer->funcs->p_wglCreateContextAttribsARB( pbuffer->hdc, prev_context, NULL ); + pbuffer->prev_context = prev_context; + } + + pbuffer->funcs->p_glGetIntegerv( binding_from_target( pbuffer->texture_target ), &prev_texture ); + + /* Switch to our pbuffer */ + pbuffer->funcs->p_wglMakeCurrent( pbuffer->hdc, pbuffer->tmp_context ); + + /* Make sure that the prev_texture is set as the current texture state isn't shared + * between contexts. After that copy the pbuffer texture data. */ + pbuffer->funcs->p_glBindTexture( pbuffer->texture_target, prev_texture ); + pbuffer->funcs->p_glCopyTexImage2D( pbuffer->texture_target, 0, pbuffer->texture_format, 0, 0, + pbuffer->width, pbuffer->height, 0 ); + + /* Switch back to the original drawable and context */ + pbuffer->funcs->p_wglMakeContextCurrentARB( prev_draw, prev_read, prev_context ); + return GL_TRUE; +} + +static BOOL win32u_wglReleaseTexImageARB( struct wgl_pbuffer *pbuffer, int buffer ) +{ + TRACE( "pbuffer %p, buffer %d\n", pbuffer, buffer ); + + if (!pbuffer->texture_format) + { + RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); + return GL_FALSE; + } + return GL_TRUE; +} + +static BOOL win32u_wglSetPbufferAttribARB( struct wgl_pbuffer *pbuffer, const int *attribs ) +{ + TRACE( "pbuffer %p, attribs %p\n", pbuffer, attribs ); + + if (!pbuffer->texture_format) + { + RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); + return GL_FALSE; + } + return GL_TRUE; +} + static void memory_funcs_init(void) { memory_funcs = osmesa_get_wgl_driver(); @@ -546,6 +846,21 @@ static void display_funcs_init(void) display_funcs->p_wglChoosePixelFormatARB = (void *)1; /* never called */ display_funcs->p_wglGetPixelFormatAttribfvARB = (void *)1; /* never called */ display_funcs->p_wglGetPixelFormatAttribivARB = (void *)1; /* never called */ + + if (driver_funcs->p_pbuffer_create) + { + register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_pbuffer" ); + display_funcs->p_wglCreatePbufferARB = win32u_wglCreatePbufferARB; + display_funcs->p_wglDestroyPbufferARB = win32u_wglDestroyPbufferARB; + display_funcs->p_wglGetPbufferDCARB = win32u_wglGetPbufferDCARB; + display_funcs->p_wglReleasePbufferDCARB = win32u_wglReleasePbufferDCARB; + display_funcs->p_wglQueryPbufferARB = win32u_wglQueryPbufferARB; + + register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_render_texture" ); + display_funcs->p_wglBindTexImageARB = win32u_wglBindTexImageARB; + display_funcs->p_wglReleaseTexImageARB = win32u_wglReleaseTexImageARB; + display_funcs->p_wglSetPbufferAttribARB = win32u_wglSetPbufferAttribARB; + } }
static struct opengl_funcs *get_dc_funcs( HDC hdc, void *null_funcs ) diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 239511b1679..5b100659630 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -236,20 +236,6 @@ struct gl_drawable HDC hdc_dst; };
-struct wgl_pbuffer -{ - struct gl_drawable *gl; - const struct glx_pixel_format* fmt; - int width; - int height; - int pixel_format; - GLint texture_format; - GLuint texture_target; - GLXContext tmp_context; - GLXContext prev_context; - struct list entry; -}; - enum glx_swap_control_method { GLX_SWAP_CONTROL_NONE, @@ -264,7 +250,6 @@ static XContext gl_hwnd_context; static XContext gl_pbuffer_context;
static struct list context_list = LIST_INIT( context_list ); -static struct list pbuffer_list = LIST_INIT( pbuffer_list ); static struct glx_pixel_format *pixel_formats; static int nb_pixel_formats, nb_onscreen_formats;
@@ -1592,19 +1577,10 @@ static struct wgl_context *glxdrv_wglCreateContext( HDC hdc ) */ static BOOL glxdrv_wglDeleteContext(struct wgl_context *ctx) { - struct wgl_pbuffer *pb; - TRACE("(%p)\n", ctx);
pthread_mutex_lock( &context_mutex ); list_remove( &ctx->entry ); - LIST_FOR_EACH_ENTRY( pb, &pbuffer_list, struct wgl_pbuffer, entry ) - { - if (pb->prev_context == ctx->ctx) { - pglXDestroyContext(gdi_display, pb->tmp_context); - pb->prev_context = pb->tmp_context = NULL; - } - } pthread_mutex_unlock( &context_mutex );
if (ctx->ctx) pglXDestroyContext( gdi_display, ctx->ctx ); @@ -1964,409 +1940,69 @@ static struct wgl_context *X11DRV_wglCreateContextAttribsARB( HDC hdc, struct wg return ret; }
-/** - * X11DRV_wglCreatePbufferARB - * - * WGL_ARB_pbuffer: wglCreatePbufferARB - */ -static struct wgl_pbuffer *X11DRV_wglCreatePbufferARB( HDC hdc, int format, int width, int height, - const int *attribs ) +static BOOL x11drv_pbuffer_create( HDC hdc, int format, BOOL largest, int *width, int *height, void **private ) { - int glx_attribs[256], count = 0, value; const struct glx_pixel_format *fmt; - struct wgl_pbuffer *object; + int glx_attribs[7], count = 0; + struct gl_drawable *surface; + RECT rect;
- TRACE( "(%p, %d, %d, %d, %p)\n", hdc, format, width, height, attribs ); + TRACE( "hdc %p, format %d, largest %u, width %d, height %d, private %p\n", hdc, format, largest, *width, *height, private );
/* Convert the WGL pixelformat to a GLX format, if it fails then the format is invalid */ if (!(fmt = get_pixel_format( gdi_display, format, TRUE /* Offscreen */ ))) { ERR( "(%p): invalid pixel format %d\n", hdc, format ); - RtlSetLastWin32Error( ERROR_INVALID_PIXEL_FORMAT ); - return NULL; - } - - if (!(object = calloc( 1, sizeof(*object) ))) - { - RtlSetLastWin32Error( ERROR_NO_SYSTEM_RESOURCES ); - return NULL; + return FALSE; } - object->width = width; - object->height = height; - object->pixel_format = format; - object->fmt = fmt;
glx_attribs[count++] = GLX_PBUFFER_WIDTH; - glx_attribs[count++] = width; + glx_attribs[count++] = *width; glx_attribs[count++] = GLX_PBUFFER_HEIGHT; - glx_attribs[count++] = height; - - while (attribs && 0 != *attribs) + glx_attribs[count++] = *height; + if (largest) { - switch (*attribs) - { - case WGL_PBUFFER_LARGEST_ARB: - ++attribs; - value = *attribs; - TRACE( "WGL_LARGEST_PBUFFER_ARB = %d\n", value ); - glx_attribs[count++] = GLX_LARGEST_PBUFFER; - glx_attribs[count++] = value; - break; - - case WGL_TEXTURE_FORMAT_ARB: - ++attribs; - value = *attribs; - TRACE( "WGL_render_texture Attribute: WGL_TEXTURE_FORMAT_ARB as %x\n", value ); - switch (value) - { - case WGL_NO_TEXTURE_ARB: - object->texture_format = 0; - break; - case WGL_TEXTURE_RGB_ARB: - object->texture_format = GL_RGB; - break; - case WGL_TEXTURE_RGBA_ARB: - object->texture_format = GL_RGBA; - break; - /* WGL_FLOAT_COMPONENTS_NV */ - case WGL_TEXTURE_FLOAT_R_NV: - object->texture_format = GL_FLOAT_R_NV; - break; - case WGL_TEXTURE_FLOAT_RG_NV: - object->texture_format = GL_FLOAT_RG_NV; - break; - case WGL_TEXTURE_FLOAT_RGB_NV: - object->texture_format = GL_FLOAT_RGB_NV; - break; - case WGL_TEXTURE_FLOAT_RGBA_NV: - object->texture_format = GL_FLOAT_RGBA_NV; - break; - default: - ERR( "Unknown texture format: %x\n", value ); - RtlSetLastWin32Error( ERROR_INVALID_DATA ); - goto create_failed; - } - break; - - case WGL_TEXTURE_TARGET_ARB: - ++attribs; - value = *attribs; - TRACE( "WGL_render_texture Attribute: WGL_TEXTURE_TARGET_ARB as %x\n", value ); - switch (value) - { - case WGL_NO_TEXTURE_ARB: - object->texture_target = 0; - break; - case WGL_TEXTURE_CUBE_MAP_ARB: - if (width != height) - { - RtlSetLastWin32Error( ERROR_INVALID_DATA ); - goto create_failed; - } - object->texture_target = GL_TEXTURE_CUBE_MAP; - break; - case WGL_TEXTURE_1D_ARB: - if (1 != height) - { - RtlSetLastWin32Error( ERROR_INVALID_DATA ); - goto create_failed; - } - object->texture_target = GL_TEXTURE_1D; - break; - case WGL_TEXTURE_2D_ARB: - object->texture_target = GL_TEXTURE_2D; - break; - case WGL_TEXTURE_RECTANGLE_NV: - object->texture_target = GL_TEXTURE_RECTANGLE_NV; - break; - default: - ERR( "Unknown texture target: %x\n", value ); - RtlSetLastWin32Error( ERROR_INVALID_DATA ); - goto create_failed; - } - break; - - case WGL_MIPMAP_TEXTURE_ARB: - ++attribs; - value = *attribs; - TRACE( "WGL_render_texture Attribute: WGL_MIPMAP_TEXTURE_ARB as %x\n", value ); - break; - } - ++attribs; + glx_attribs[count++] = GLX_LARGEST_PBUFFER; + glx_attribs[count++] = 1; } glx_attribs[count++] = 0;
- if (!(object->gl = calloc( 1, sizeof(*object->gl) ))) - { - RtlSetLastWin32Error( ERROR_NO_SYSTEM_RESOURCES ); - goto create_failed; - } - object->gl->type = DC_GL_PBUFFER; - object->gl->format = object->fmt; - object->gl->ref = 1; + if (!(surface = calloc( 1, sizeof(*surface) ))) return FALSE; + surface->type = DC_GL_PBUFFER; + surface->format = fmt; + surface->ref = 1;
- object->gl->drawable = pglXCreatePbuffer( gdi_display, fmt->fbconfig, glx_attribs ); - TRACE( "new Pbuffer drawable as %p (%lx)\n", object->gl, object->gl->drawable ); - if (!object->gl->drawable) + surface->drawable = pglXCreatePbuffer( gdi_display, fmt->fbconfig, glx_attribs ); + TRACE( "new Pbuffer drawable as %p (%lx)\n", surface, surface->drawable ); + if (!surface->drawable) { - free( object->gl ); - RtlSetLastWin32Error( ERROR_NO_SYSTEM_RESOURCES ); - goto create_failed; /* unexpected error */ + free( surface ); + return FALSE; } - pthread_mutex_lock( &context_mutex ); - list_add_head( &pbuffer_list, &object->entry ); - pthread_mutex_unlock( &context_mutex ); - TRACE( "->(%p)\n", object ); - return object; - -create_failed: - free( object ); - TRACE( "->(FAILED)\n" ); - return NULL; -} - -/** - * X11DRV_wglDestroyPbufferARB - * - * WGL_ARB_pbuffer: wglDestroyPbufferARB - */ -static BOOL X11DRV_wglDestroyPbufferARB( struct wgl_pbuffer *object ) -{ - TRACE("(%p)\n", object); + pglXQueryDrawable( gdi_display, surface->drawable, GLX_WIDTH, (unsigned int *)width ); + pglXQueryDrawable( gdi_display, surface->drawable, GLX_HEIGHT, (unsigned int *)height ); + SetRect( &rect, 0, 0, *width, *height ); + set_dc_drawable( hdc, surface->drawable, &rect, IncludeInferiors );
pthread_mutex_lock( &context_mutex ); - list_remove( &object->entry ); + XSaveContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char *)surface ); pthread_mutex_unlock( &context_mutex ); - release_gl_drawable( object->gl ); - if (object->tmp_context) - pglXDestroyContext(gdi_display, object->tmp_context); - free( object ); - return GL_TRUE; -} - -/** - * X11DRV_wglGetPbufferDCARB - * - * WGL_ARB_pbuffer: wglGetPbufferDCARB - */ -static HDC X11DRV_wglGetPbufferDCARB( struct wgl_pbuffer *object ) -{ - struct x11drv_escape_set_drawable escape; - struct gl_drawable *prev; - HDC hdc; - - hdc = NtGdiOpenDCW( NULL, NULL, NULL, 0, TRUE, NULL, NULL, NULL ); - if (!hdc) return 0; - - pthread_mutex_lock( &context_mutex ); - if (!XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&prev )) - release_gl_drawable( prev ); - grab_gl_drawable( object->gl ); - XSaveContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char *)object->gl ); - pthread_mutex_unlock( &context_mutex ); - - escape.code = X11DRV_SET_DRAWABLE; - escape.drawable = object->gl->drawable; - escape.mode = IncludeInferiors; - SetRect( &escape.dc_rect, 0, 0, object->width, object->height ); - escape.visual = default_visual; - NtGdiExtEscape( hdc, NULL, 0, X11DRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL ); - - NtGdiSetPixelFormat( hdc, object->pixel_format ); - TRACE( "(%p)->(%p)\n", object, hdc ); - return hdc; -} - -/** - * X11DRV_wglQueryPbufferARB - * - * WGL_ARB_pbuffer: wglQueryPbufferARB - */ -static BOOL X11DRV_wglQueryPbufferARB( struct wgl_pbuffer *object, int attrib, int *value ) -{ - TRACE( "(%p, 0x%x, %p)\n", object, attrib, value ); - - switch (attrib) - { - case WGL_PBUFFER_WIDTH_ARB: - pglXQueryDrawable( gdi_display, object->gl->drawable, GLX_WIDTH, (unsigned int *)value ); - break; - case WGL_PBUFFER_HEIGHT_ARB: - pglXQueryDrawable( gdi_display, object->gl->drawable, GLX_HEIGHT, (unsigned int *)value ); - break; - - case WGL_PBUFFER_LOST_ARB: - /* GLX Pbuffers cannot be lost by default. We can support this by - * setting GLX_PRESERVED_CONTENTS to False and using glXSelectEvent - * to receive pixel buffer clobber events, however that may or may - * not give any benefit */ - *value = GL_FALSE; - break;
- case WGL_TEXTURE_FORMAT_ARB: - switch (object->texture_format) - { - case 0: *value = WGL_NO_TEXTURE_ARB; break; - case GL_RGB: *value = WGL_TEXTURE_RGB_ARB; break; - case GL_RGBA: *value = WGL_TEXTURE_RGBA_ARB; break; - /* WGL_FLOAT_COMPONENTS_NV */ - case GL_FLOAT_R_NV: *value = WGL_TEXTURE_FLOAT_R_NV; break; - case GL_FLOAT_RG_NV: *value = WGL_TEXTURE_FLOAT_RG_NV; break; - case GL_FLOAT_RGB_NV: *value = WGL_TEXTURE_FLOAT_RGB_NV; break; - case GL_FLOAT_RGBA_NV: *value = WGL_TEXTURE_FLOAT_RGBA_NV; break; - default: ERR( "Unknown texture format: %x\n", object->texture_format ); - } - break; - - case WGL_TEXTURE_TARGET_ARB: - switch (object->texture_target) - { - case 0: *value = WGL_NO_TEXTURE_ARB; break; - case GL_TEXTURE_1D: *value = WGL_TEXTURE_1D_ARB; break; - case GL_TEXTURE_2D: *value = WGL_TEXTURE_2D_ARB; break; - case GL_TEXTURE_CUBE_MAP: *value = WGL_TEXTURE_CUBE_MAP_ARB; break; - case GL_TEXTURE_RECTANGLE_NV: *value = WGL_TEXTURE_RECTANGLE_NV; break; - } - break; - - case WGL_MIPMAP_TEXTURE_ARB: - *value = GL_FALSE; /** don't support that */ - FIXME( "unsupported WGL_ARB_render_texture attribute query for 0x%x\n", attrib ); - break; - - default: FIXME( "unexpected attribute %x\n", attrib ); break; - } - - return GL_TRUE; + *private = surface; + return TRUE; }
-/** - * X11DRV_wglReleasePbufferDCARB - * - * WGL_ARB_pbuffer: wglReleasePbufferDCARB - */ -static int X11DRV_wglReleasePbufferDCARB( struct wgl_pbuffer *object, HDC hdc ) +static BOOL x11drv_pbuffer_destroy( HDC hdc, void *private ) { - struct gl_drawable *gl; + struct gl_drawable *surface = private;
- TRACE("(%p, %p)\n", object, hdc); + TRACE( "hdc %p, private %p\n", hdc, surface );
pthread_mutex_lock( &context_mutex ); - - if (!XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&gl )) - { - XDeleteContext( gdi_display, (XID)hdc, gl_pbuffer_context ); - release_gl_drawable( gl ); - } - else hdc = 0; - + XDeleteContext( gdi_display, (XID)hdc, gl_pbuffer_context ); pthread_mutex_unlock( &context_mutex ); + release_gl_drawable( surface );
- return hdc && NtGdiDeleteObjectApp(hdc); -} - -/** - * X11DRV_wglSetPbufferAttribARB - * - * WGL_ARB_pbuffer: wglSetPbufferAttribARB - */ -static BOOL X11DRV_wglSetPbufferAttribARB( struct wgl_pbuffer *object, const int *piAttribList ) -{ - WARN("(%p, %p): alpha-testing, report any problem\n", object, piAttribList); - - if (!object->texture_format) - { - RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); - return GL_FALSE; - } - return GL_TRUE; -} - -static GLenum binding_from_target( GLenum target ) -{ - switch (target) - { - case GL_TEXTURE_CUBE_MAP: return GL_TEXTURE_BINDING_CUBE_MAP; - case GL_TEXTURE_1D: return GL_TEXTURE_BINDING_1D; - case GL_TEXTURE_2D: return GL_TEXTURE_BINDING_2D; - case GL_TEXTURE_RECTANGLE_NV: return GL_TEXTURE_BINDING_RECTANGLE_NV; - } - FIXME( "Unsupported target %#x\n", target ); - return 0; -} - -/** - * X11DRV_wglBindTexImageARB - * - * WGL_ARB_render_texture: wglBindTexImageARB - */ -static BOOL X11DRV_wglBindTexImageARB( struct wgl_pbuffer *object, int iBuffer ) -{ - static BOOL initialized = FALSE; - int prev_binded_texture = 0; - GLXContext prev_context; - GLXDrawable prev_drawable; - - TRACE("(%p, %d)\n", object, iBuffer); - - if (!object->texture_format) - { - RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); - return GL_FALSE; - } - - prev_context = pglXGetCurrentContext(); - prev_drawable = pglXGetCurrentDrawable(); - - /* Our render_texture emulation is basic and lacks some features (1D/Cube support). - This is mostly due to lack of demos/games using them. Further the use of glReadPixels - isn't ideal performance wise but I wasn't able to get other ways working. - */ - if (!initialized) - { - initialized = TRUE; /* Only show the FIXME once for performance reasons */ - FIXME( "partial stub!\n" ); - } - - TRACE( "drawable=%p (%lx), context=%p\n", object->gl, object->gl->drawable, prev_context ); - if (!object->tmp_context || object->prev_context != prev_context) - { - if (object->tmp_context) pglXDestroyContext( gdi_display, object->tmp_context ); - object->tmp_context = pglXCreateNewContext( gdi_display, object->fmt->fbconfig, - object->fmt->render_type, prev_context, True ); - object->prev_context = prev_context; - } - - opengl_funcs.p_glGetIntegerv( binding_from_target( object->texture_target ), &prev_binded_texture ); - - /* Switch to our pbuffer */ - pglXMakeCurrent( gdi_display, object->gl->drawable, object->tmp_context ); - - /* Make sure that the prev_binded_texture is set as the current texture state isn't shared - * between contexts. After that copy the pbuffer texture data. */ - opengl_funcs.p_glBindTexture( object->texture_target, prev_binded_texture ); - opengl_funcs.p_glCopyTexImage2D( object->texture_target, 0, object->texture_format, 0, 0, - object->width, object->height, 0 ); - - /* Switch back to the original drawable and context */ - pglXMakeCurrent( gdi_display, prev_drawable, prev_context ); - return GL_TRUE; -} - -/** - * X11DRV_wglReleaseTexImageARB - * - * WGL_ARB_render_texture: wglReleaseTexImageARB - */ -static BOOL X11DRV_wglReleaseTexImageARB( struct wgl_pbuffer *object, int iBuffer ) -{ - TRACE("(%p, %d)\n", object, iBuffer); - - if (!object->texture_format) - { - RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); - return GL_FALSE; - } return GL_TRUE; }
@@ -2506,17 +2142,6 @@ static const char *x11drv_init_wgl_extensions(void)
if (has_extension( glxExtensions, "GLX_ARB_multisample")) register_extension( "WGL_ARB_multisample" );
- if (glxRequireVersion(3)) - { - register_extension( "WGL_ARB_pbuffer" ); - opengl_funcs.p_wglCreatePbufferARB = X11DRV_wglCreatePbufferARB; - opengl_funcs.p_wglDestroyPbufferARB = X11DRV_wglDestroyPbufferARB; - opengl_funcs.p_wglGetPbufferDCARB = X11DRV_wglGetPbufferDCARB; - opengl_funcs.p_wglQueryPbufferARB = X11DRV_wglQueryPbufferARB; - opengl_funcs.p_wglReleasePbufferDCARB = X11DRV_wglReleasePbufferDCARB; - opengl_funcs.p_wglSetPbufferAttribARB = X11DRV_wglSetPbufferAttribARB; - } - if (has_extension( glxExtensions, "GLX_ARB_fbconfig_float")) { register_extension("WGL_ARB_pixel_format_float"); @@ -2526,10 +2151,6 @@ static const char *x11drv_init_wgl_extensions(void) /* Support WGL_ARB_render_texture when there's support or pbuffer based emulation */ if (has_extension( glxExtensions, "GLX_ARB_render_texture" ) || glxRequireVersion( 3 )) { - register_extension( "WGL_ARB_render_texture" ); - opengl_funcs.p_wglBindTexImageARB = X11DRV_wglBindTexImageARB; - opengl_funcs.p_wglReleaseTexImageARB = X11DRV_wglReleaseTexImageARB; - /* The WGL version of GLX_NV_float_buffer requires render_texture */ if (has_extension( glxExtensions, "GLX_NV_float_buffer")) register_extension("WGL_NV_float_buffer"); @@ -2678,6 +2299,8 @@ static const struct opengl_driver_funcs x11drv_driver_funcs = .p_describe_pixel_format = x11drv_describe_pixel_format, .p_init_wgl_extensions = x11drv_init_wgl_extensions, .p_set_pixel_format = x11drv_set_pixel_format, + .p_pbuffer_create = x11drv_pbuffer_create, + .p_pbuffer_destroy = x11drv_pbuffer_destroy, };
static struct opengl_funcs opengl_funcs = diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index f652a58c920..11bcbe6758a 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -117,6 +117,9 @@ struct opengl_driver_funcs BOOL (*p_describe_pixel_format)(int,struct wgl_pixel_format*); const char *(*p_init_wgl_extensions)(void); BOOL (*p_set_pixel_format)(HWND,int,int,BOOL); + + BOOL (*p_pbuffer_create)(HDC,int,BOOL,GLsizei*,GLsizei*,void **); + BOOL (*p_pbuffer_destroy)(HDC,void*); };
#endif /* WINE_UNIX_LIB */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/opengl.c | 361 +++------------------------------- 1 file changed, 27 insertions(+), 334 deletions(-)
diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index 9c4e7234d3d..cb15846ae53 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -79,14 +79,13 @@ DECL_FUNCPTR(glClear); static pthread_mutex_t gl_object_mutex = PTHREAD_MUTEX_INITIALIZER; static struct list gl_drawables = LIST_INIT(gl_drawables); static struct list gl_contexts = LIST_INIT(gl_contexts); -static struct list gl_pbuffer_dcs = LIST_INIT(gl_pbuffer_dcs); -static struct list gl_pbuffers = LIST_INIT(gl_pbuffers);
struct wayland_gl_drawable { struct list entry; LONG ref; HWND hwnd; + HDC hdc; struct wayland_client_surface *client; struct wl_egl_window *wl_egl_window; EGLSurface surface; @@ -126,16 +125,10 @@ struct wayland_pbuffer_dc static struct wayland_gl_drawable *find_drawable(HWND hwnd, HDC hdc) { struct wayland_gl_drawable *gl; - struct wayland_pbuffer_dc *pb; - if (hwnd) - { - LIST_FOR_EACH_ENTRY(gl, &gl_drawables, struct wayland_gl_drawable, entry) - if (gl->hwnd == hwnd) return gl; - } - if (hdc) + LIST_FOR_EACH_ENTRY(gl, &gl_drawables, struct wayland_gl_drawable, entry) { - LIST_FOR_EACH_ENTRY(pb, &gl_pbuffer_dcs, struct wayland_pbuffer_dc, entry) - if (pb->hdc == hdc) return pb->gl; + if (hwnd && gl->hwnd == hwnd) return gl; + if (hdc && gl->hdc == hdc) return gl; } return NULL; } @@ -189,11 +182,9 @@ static inline EGLConfig egl_config_for_format(int format) return egl_configs[format - num_egl_configs - 1]; }
-static struct wayland_gl_drawable *wayland_gl_drawable_create(HWND hwnd, int format) +static struct wayland_gl_drawable *wayland_gl_drawable_create(HWND hwnd, HDC hdc, int format, int width, int height) { struct wayland_gl_drawable *gl; - int client_width, client_height; - RECT client_rect = {0}; const EGLint attribs[] = {EGL_PRESENT_OPAQUE_EXT, EGL_TRUE, EGL_NONE};
TRACE("hwnd=%p format=%d\n", hwnd, format); @@ -203,20 +194,15 @@ static struct wayland_gl_drawable *wayland_gl_drawable_create(HWND hwnd, int for
gl->ref = 1; gl->hwnd = hwnd; + gl->hdc = hdc; gl->swap_interval = 1;
- NtUserGetClientRect(gl->hwnd, &client_rect, NtUserGetDpiForWindow(gl->hwnd)); - client_width = client_rect.right - client_rect.left; - client_height = client_rect.bottom - client_rect.top; - if (client_width == 0 || client_height == 0) client_width = client_height = 1; - /* Get the client surface for the HWND. If don't have a wayland surface * (e.g., HWND_MESSAGE windows) just create a dummy surface to act as the * target render surface. */ if (!(gl->client = get_client_surface(hwnd))) goto err;
- gl->wl_egl_window = wl_egl_window_create(gl->client->wl_surface, - client_width, client_height); + gl->wl_egl_window = wl_egl_window_create(gl->client->wl_surface, width, height); if (!gl->wl_egl_window) { ERR("Failed to create wl_egl_window\n"); @@ -435,6 +421,7 @@ static void wgl_context_refresh(struct wgl_context *ctx) static BOOL wayland_set_pixel_format(HWND hwnd, int old_format, int new_format, BOOL internal) { struct wayland_gl_drawable *gl; + RECT rect;
/* Even for internal pixel format fail setting it if the app has already set a * different pixel format. Let wined3d create a backup GL context instead. @@ -442,7 +429,11 @@ static BOOL wayland_set_pixel_format(HWND hwnd, int old_format, int new_format, * than blitting from backup context. */ if (old_format) return old_format == new_format;
- if (!(gl = wayland_gl_drawable_create(hwnd, new_format))) return FALSE; + NtUserGetClientRect(hwnd, &rect, NtUserGetDpiForWindow(hwnd)); + if (rect.right == rect.left) rect.right = rect.left + 1; + if (rect.bottom == rect.top) rect.bottom = rect.top + 1; + + if (!(gl = wayland_gl_drawable_create(hwnd, 0, new_format, rect.right - rect.left, rect.bottom - rect.top))) return FALSE; wayland_update_gl_drawable(hwnd, gl); return TRUE; } @@ -490,41 +481,6 @@ out: return ctx; }
-static struct wayland_gl_drawable *clear_pbuffer_dc(HDC hdc) -{ - struct wayland_pbuffer_dc *pd; - struct wayland_gl_drawable *gl; - - LIST_FOR_EACH_ENTRY(pd, &gl_pbuffer_dcs, struct wayland_pbuffer_dc, entry) - { - if (pd->hdc == hdc) - { - list_remove(&pd->entry); - gl = pd->gl; - free(pd); - return gl; - } - } - - return NULL; -} - -static BOOL set_pbuffer_dc(struct wgl_pbuffer *pbuffer, HDC hdc) -{ - struct wayland_pbuffer_dc *pd; - - if (!(pd = calloc(1, sizeof(*pd)))) - { - ERR("Failed to allocate memory for pbuffer HDC mapping\n"); - return FALSE; - } - pd->hdc = hdc; - pd->gl = wayland_gl_drawable_acquire(pbuffer->gl); - list_add_head(&gl_pbuffer_dcs, &pd->entry); - - return TRUE; -} - void wayland_glClear(GLbitfield mask) { struct wgl_context *ctx = NtCurrentTeb()->glContext; @@ -557,18 +513,8 @@ static struct wgl_context *wayland_wglCreateContextAttribsARB(HDC hdc,
static BOOL wayland_wglDeleteContext(struct wgl_context *ctx) { - struct wgl_pbuffer *pb; - pthread_mutex_lock(&gl_object_mutex); list_remove(&ctx->entry); - LIST_FOR_EACH_ENTRY(pb, &gl_pbuffers, struct wgl_pbuffer, entry) - { - if (pb->prev_context == ctx->context) - { - p_eglDestroyContext(egl_display, pb->tmp_context); - pb->prev_context = pb->tmp_context = NULL; - } - } pthread_mutex_unlock(&gl_object_mutex); p_eglDestroyContext(egl_display, ctx->context); if (ctx->draw) wayland_gl_drawable_release(ctx->draw); @@ -717,278 +663,35 @@ static BOOL wayland_wglSwapIntervalEXT(int interval) return ret; }
-static struct wgl_pbuffer *wayland_wglCreatePbufferARB(HDC hdc, int format, - int width, int height, - const int *attribs) +static BOOL wayland_pbuffer_create(HDC hdc, int format, BOOL largest, int *width, int *height, void **private) { - struct wgl_pbuffer *pbuffer; + struct wayland_gl_drawable *drawable;
- TRACE("(%p, %d, %d, %d, %p)\n", hdc, format, width, height, attribs); - - if (format <= 0 || format > 2 * num_egl_configs) - { - RtlSetLastWin32Error(ERROR_INVALID_PIXEL_FORMAT); - ERR("Invalid format %d\n", format); - return NULL; - } + TRACE("hdc %p, format %d, largest %u, width %d, height %d, private %p\n", hdc, format, largest, *width, *height, private);
/* Use an unmapped wayland surface as our offscreen "pbuffer" surface. */ - if (!(pbuffer = calloc(1, sizeof(*pbuffer))) || - !(pbuffer->gl = wayland_gl_drawable_create(0, format))) - { - RtlSetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); - free(pbuffer); - return NULL; - } - - pbuffer->width = width; - pbuffer->height = height; - pbuffer->pixel_format = format; - wl_egl_window_resize(pbuffer->gl->wl_egl_window, width, height, 0, 0); - - for (; attribs && attribs[0]; attribs += 2) - { - switch (attribs[0]) - { - case WGL_TEXTURE_FORMAT_ARB: - TRACE("attribs[WGL_TEXTURE_FORMAT_ARB]=0x%x\n", attribs[1]); - switch(attribs[1]) - { - case WGL_NO_TEXTURE_ARB: - pbuffer->texture_format = 0; - break; - case WGL_TEXTURE_RGB_ARB: - pbuffer->texture_format = GL_RGB; - break; - case WGL_TEXTURE_RGBA_ARB: - pbuffer->texture_format = GL_RGBA; - break; - /* WGL_FLOAT_COMPONENTS_NV */ - case WGL_TEXTURE_FLOAT_R_NV: - pbuffer->texture_format = GL_FLOAT_R_NV; - break; - case WGL_TEXTURE_FLOAT_RG_NV: - pbuffer->texture_format = GL_FLOAT_RG_NV; - break; - case WGL_TEXTURE_FLOAT_RGB_NV: - pbuffer->texture_format = GL_FLOAT_RGB_NV; - break; - case WGL_TEXTURE_FLOAT_RGBA_NV: - pbuffer->texture_format = GL_FLOAT_RGBA_NV; - break; - default: - ERR("Unknown texture format: %x\n", attribs[1]); - } - break; - - case WGL_TEXTURE_TARGET_ARB: - TRACE("attribs[WGL_TEXTURE_TARGET_ARB]=0x%x\n", attribs[1]); - switch (attribs[1]) - { - case WGL_TEXTURE_CUBE_MAP_ARB: - if (width != height) goto err; - pbuffer->texture_target = GL_TEXTURE_CUBE_MAP; - pbuffer->texture_binding = GL_TEXTURE_BINDING_CUBE_MAP; - break; - case WGL_TEXTURE_1D_ARB: - if (height != 1) goto err; - pbuffer->texture_target = GL_TEXTURE_1D; - pbuffer->texture_binding = GL_TEXTURE_BINDING_1D; - break; - case WGL_TEXTURE_2D_ARB: - pbuffer->texture_target = GL_TEXTURE_2D; - pbuffer->texture_binding = GL_TEXTURE_BINDING_2D; - break; - case WGL_TEXTURE_RECTANGLE_NV: - pbuffer->texture_target = GL_TEXTURE_RECTANGLE_NV; - pbuffer->texture_binding = GL_TEXTURE_BINDING_RECTANGLE_NV; - break; - default: - ERR("Unknown texture target: %x\n", attribs[1]); - goto err; - } - break; - - case WGL_MIPMAP_TEXTURE_ARB: - TRACE("attribs[WGL_MIPMAP_TEXTURE_ARB]=0x%x\n", attribs[1]); - break; - - default: - WARN("Unknown attribute: %x\n", attribs[0]); - break; - } - } - - pthread_mutex_lock(&gl_object_mutex); - list_add_head(&gl_pbuffers, &pbuffer->entry); - pthread_mutex_unlock(&gl_object_mutex); - - return pbuffer; - -err: - RtlSetLastWin32Error(ERROR_INVALID_DATA); - wayland_gl_drawable_release(pbuffer->gl); - free(pbuffer); - return NULL; -} - -static BOOL wayland_wglDestroyPbufferARB(struct wgl_pbuffer *pbuffer) -{ - TRACE("(%p)\n", pbuffer); - - pthread_mutex_lock(&gl_object_mutex); - list_remove(&pbuffer->entry); - pthread_mutex_unlock(&gl_object_mutex); - - if (pbuffer->tmp_context) p_eglDestroyContext(egl_display, pbuffer->tmp_context); - wayland_gl_drawable_release(pbuffer->gl); - free(pbuffer); - - return GL_TRUE; -} - -static HDC wayland_wglGetPbufferDCARB(struct wgl_pbuffer *pbuffer) -{ - HDC hdc; - BOOL set; - struct wayland_gl_drawable *old; - - if (!(hdc = NtGdiOpenDCW(NULL, NULL, NULL, 0, TRUE, NULL, NULL, NULL))) return 0; + if (!(drawable = wayland_gl_drawable_create(0, hdc, format, *width, *height))) return FALSE;
pthread_mutex_lock(&gl_object_mutex); - old = clear_pbuffer_dc(hdc); - set = set_pbuffer_dc(pbuffer, hdc); + list_add_head(&gl_drawables, &drawable->entry); pthread_mutex_unlock(&gl_object_mutex);
- if (old) wayland_gl_drawable_release(old); - if (!set) - { - NtGdiDeleteObjectApp(hdc); - return 0; - } - - NtGdiSetPixelFormat(hdc, pbuffer->pixel_format); - return hdc; + *private = drawable; + return TRUE; }
-static BOOL wayland_wglQueryPbufferARB(struct wgl_pbuffer *pbuffer, int attrib, int *value) +static BOOL wayland_pbuffer_destroy(HDC hdc, void *private) { - TRACE("(%p, 0x%x, %p)\n", pbuffer, attrib, value); - - switch (attrib) - { - case WGL_PBUFFER_WIDTH_ARB: *value = pbuffer->width; break; - case WGL_PBUFFER_HEIGHT_ARB: *value = pbuffer->height; break; - case WGL_PBUFFER_LOST_ARB: *value = GL_FALSE; break; - case WGL_TEXTURE_FORMAT_ARB: - switch(pbuffer->texture_format) - { - case GL_RGB: *value = WGL_TEXTURE_RGB_ARB; break; - case GL_RGBA: *value = WGL_TEXTURE_RGBA_ARB; break; - case GL_FLOAT_R_NV: *value = WGL_TEXTURE_FLOAT_R_NV; break; - case GL_FLOAT_RG_NV: *value = WGL_TEXTURE_FLOAT_RG_NV; break; - case GL_FLOAT_RGB_NV: *value = WGL_TEXTURE_FLOAT_RGB_NV; break; - case GL_FLOAT_RGBA_NV: *value = WGL_TEXTURE_FLOAT_RGBA_NV; break; - default: - ERR("Unknown texture format: %x\n", pbuffer->texture_format); - break; - } - break; - case WGL_TEXTURE_TARGET_ARB: - switch (pbuffer->texture_target) - { - case GL_TEXTURE_1D: *value = WGL_TEXTURE_1D_ARB; break; - case GL_TEXTURE_2D: *value = WGL_TEXTURE_2D_ARB; break; - case GL_TEXTURE_CUBE_MAP: *value = WGL_TEXTURE_CUBE_MAP_ARB; break; - case GL_TEXTURE_RECTANGLE_NV: *value = WGL_TEXTURE_RECTANGLE_NV; break; - default: - ERR("Unknown texture target: %x\n", pbuffer->texture_target); - break; - } - break; - case WGL_MIPMAP_TEXTURE_ARB: - *value = GL_FALSE; - FIXME("unsupported attribute query for 0x%x\n", attrib); - break; - default: - FIXME("unexpected attribute %x\n", attrib); - break; - } - - return GL_TRUE; -} + struct wayland_gl_drawable *drawable = private;
-static int wayland_wglReleasePbufferDCARB(struct wgl_pbuffer *pbuffer, HDC hdc) -{ - struct wayland_gl_drawable *old; + TRACE("hdc %p, private %p\n", hdc, private);
pthread_mutex_lock(&gl_object_mutex); - old = clear_pbuffer_dc(hdc); + list_remove(&drawable->entry); pthread_mutex_unlock(&gl_object_mutex);
- if (old) wayland_gl_drawable_release(old); - else hdc = 0; - - return hdc && NtGdiDeleteObjectApp(hdc); -} - -static BOOL wayland_wglBindTexImageARB(struct wgl_pbuffer *pbuffer, int buffer) -{ - EGLContext prev_context = p_eglGetCurrentContext(); - EGLSurface prev_draw = p_eglGetCurrentSurface(EGL_DRAW); - EGLSurface prev_read = p_eglGetCurrentSurface(EGL_READ); - int prev_bound_texture = 0; - - TRACE("(%p, %d)\n", pbuffer, buffer); - - if (!pbuffer->tmp_context || pbuffer->prev_context != prev_context) - { - if (pbuffer->tmp_context) p_eglDestroyContext(egl_display, pbuffer->tmp_context); - p_eglBindAPI(EGL_OPENGL_API); - pbuffer->tmp_context = - p_eglCreateContext(egl_display, EGL_NO_CONFIG_KHR, prev_context, NULL); - pbuffer->prev_context = prev_context; - } - - opengl_funcs.p_glGetIntegerv(pbuffer->texture_binding, &prev_bound_texture); - - p_eglMakeCurrent(egl_display, pbuffer->gl->surface, pbuffer->gl->surface, - pbuffer->tmp_context); - - /* Make sure that the prev_bound_texture is set as the current texture - * state isn't shared between contexts. After that copy the pbuffer texture - * data. Note that at the moment we ignore the 'buffer' argument and always - * copy from the pbuffer back buffer. */ - opengl_funcs.p_glBindTexture(pbuffer->texture_target, prev_bound_texture); - opengl_funcs.p_glCopyTexImage2D(pbuffer->texture_target, 0, - pbuffer->texture_format, 0, 0, - pbuffer->width, pbuffer->height, 0); + wayland_gl_drawable_release(drawable);
- /* Switch back to the original surface and context. */ - p_eglMakeCurrent(egl_display, prev_draw, prev_read, prev_context); - - return GL_TRUE; -} - -static BOOL wayland_wglReleaseTexImageARB(struct wgl_pbuffer *pbuffer, int buffer) -{ - TRACE("(%p, %d)\n", pbuffer, buffer); - - if (!pbuffer->texture_format) - { - RtlSetLastWin32Error(ERROR_INVALID_HANDLE); - return GL_FALSE; - } - return GL_TRUE; -} - -static BOOL wayland_wglSetPbufferAttribARB(struct wgl_pbuffer *pbuffer, const int *attribs) -{ - if (!pbuffer->texture_format) - { - RtlSetLastWin32Error(ERROR_INVALID_HANDLE); - return GL_FALSE; - } return GL_TRUE; }
@@ -1191,18 +894,6 @@ static const char *wayland_init_wgl_extensions(void) register_extension("WGL_ATI_pixel_format_float"); }
- register_extension("WGL_ARB_pbuffer"); - opengl_funcs.p_wglCreatePbufferARB = wayland_wglCreatePbufferARB; - opengl_funcs.p_wglDestroyPbufferARB = wayland_wglDestroyPbufferARB; - opengl_funcs.p_wglGetPbufferDCARB = wayland_wglGetPbufferDCARB; - opengl_funcs.p_wglQueryPbufferARB = wayland_wglQueryPbufferARB; - opengl_funcs.p_wglReleasePbufferDCARB = wayland_wglReleasePbufferDCARB; - - register_extension("WGL_ARB_render_texture"); - opengl_funcs.p_wglBindTexImageARB = wayland_wglBindTexImageARB; - opengl_funcs.p_wglReleaseTexImageARB = wayland_wglReleaseTexImageARB; - opengl_funcs.p_wglSetPbufferAttribARB = wayland_wglSetPbufferAttribARB; - return wgl_extensions; }
@@ -1267,6 +958,8 @@ static const struct opengl_driver_funcs wayland_driver_funcs = .p_describe_pixel_format = wayland_describe_pixel_format, .p_init_wgl_extensions = wayland_init_wgl_extensions, .p_set_pixel_format = wayland_set_pixel_format, + .p_pbuffer_create = wayland_pbuffer_create, + .p_pbuffer_destroy = wayland_pbuffer_destroy, };
/**********************************************************************
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/tests/opengl.c | 54 ++-- dlls/win32u/opengl.c | 146 ++++++++- dlls/winemac.drv/opengl.c | 542 ++++------------------------------ dlls/winewayland.drv/opengl.c | 20 +- dlls/winex11.drv/opengl.c | 20 +- include/wine/opengl_driver.h | 4 +- 6 files changed, 261 insertions(+), 525 deletions(-)
diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index c1fe8ac1245..868cb41ee70 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -330,11 +330,11 @@ static void test_pbuffers( HDC old_hdc ) value = 0xdeadbeef; ret = pwglQueryPbufferARB( pbuffer, WGL_MIPMAP_LEVEL_ARB, &value ); ok( ret == 1, "got %u\n", ret ); - todo_wine ok( value == 0 || broken(value > 0) /* AMD */, "got %u\n", value ); + ok( value == 0 || broken(value > 0) /* AMD */, "got %u\n", value ); value = 0xdeadbeef; ret = pwglQueryPbufferARB( pbuffer, WGL_CUBE_MAP_FACE_ARB, &value ); ok( ret == 1, "got %u\n", ret ); - todo_wine ok( value == WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB || broken(value == 0xdeadbeef), "got %#x\n", value ); + ok( value == WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB || broken(value == 0xdeadbeef), "got %#x\n", value );
pbuffer_attribs[0] = WGL_PBUFFER_WIDTH_ARB; pbuffer_attribs[1] = 50; @@ -450,64 +450,64 @@ static void test_pbuffers( HDC old_hdc ) value = 0xdeadbeef; ret = pwglQueryPbufferARB( pbuffer, WGL_MIPMAP_TEXTURE_ARB, &value ); ok( ret == 1, "got %u\n", ret ); - todo_wine ok( value == 1 || broken(value > 0) /* AMD */, "got %u\n", value ); + ok( value == 1 || broken(value > 0) /* AMD */, "got %u\n", value ); value = 0xdeadbeef; ret = pwglQueryPbufferARB( pbuffer, WGL_MIPMAP_LEVEL_ARB, &value ); ok( ret == 1, "got %u\n", ret ); - todo_wine ok( value == 0 || broken(value > 0) /* AMD */, "got %u\n", value ); + ok( value == 0 || broken(value > 0) /* AMD */, "got %u\n", value ); value = 0xdeadbeef; ret = pwglQueryPbufferARB( pbuffer, WGL_CUBE_MAP_FACE_ARB, &value ); ok( ret == 1, "got %u\n", ret ); - todo_wine ok( value == WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB || broken(value == 0xdeadbeef) /* AMD */, "got %#x\n", value ); + ok( value == WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB || broken(value == 0xdeadbeef) /* AMD */, "got %#x\n", value );
pbuffer_attribs[0] = WGL_PBUFFER_WIDTH_ARB; pbuffer_attribs[1] = 50; SetLastError( 0xdeadbeef ); ret = pwglSetPbufferAttribARB( pbuffer, pbuffer_attribs ); - todo_wine ok( ret == 0, "got %u\n", ret ); - todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + ok( ret == 0, "got %u\n", ret ); + ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); pbuffer_attribs[0] = WGL_PBUFFER_HEIGHT_ARB; pbuffer_attribs[1] = 50; SetLastError( 0xdeadbeef ); ret = pwglSetPbufferAttribARB( pbuffer, pbuffer_attribs ); - todo_wine ok( ret == 0, "got %u\n", ret ); - todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + ok( ret == 0, "got %u\n", ret ); + ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); pbuffer_attribs[0] = WGL_PBUFFER_LOST_ARB; pbuffer_attribs[1] = 0; SetLastError( 0xdeadbeef ); ret = pwglSetPbufferAttribARB( pbuffer, pbuffer_attribs ); - todo_wine ok( ret == 0, "got %u\n", ret ); - todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + ok( ret == 0, "got %u\n", ret ); + ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); pbuffer_attribs[0] = WGL_TEXTURE_FORMAT_ARB; pbuffer_attribs[1] = WGL_TEXTURE_RGBA_ARB; SetLastError( 0xdeadbeef ); ret = pwglSetPbufferAttribARB( pbuffer, pbuffer_attribs ); - todo_wine ok( ret == 0, "got %u\n", ret ); - todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + ok( ret == 0, "got %u\n", ret ); + ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); pbuffer_attribs[0] = WGL_TEXTURE_TARGET_ARB; pbuffer_attribs[1] = WGL_TEXTURE_2D_ARB; SetLastError( 0xdeadbeef ); ret = pwglSetPbufferAttribARB( pbuffer, pbuffer_attribs ); - todo_wine ok( ret == 0, "got %u\n", ret ); - todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + ok( ret == 0, "got %u\n", ret ); + ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); pbuffer_attribs[0] = WGL_MIPMAP_TEXTURE_ARB; pbuffer_attribs[1] = 2; SetLastError( 0xdeadbeef ); ret = pwglSetPbufferAttribARB( pbuffer, pbuffer_attribs ); - todo_wine ok( ret == 0, "got %u\n", ret ); - todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + ok( ret == 0, "got %u\n", ret ); + ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); pbuffer_attribs[0] = WGL_MIPMAP_LEVEL_ARB; pbuffer_attribs[1] = 2; SetLastError( 0xdeadbeef ); ret = pwglSetPbufferAttribARB( pbuffer, pbuffer_attribs ); - todo_wine ok( ret == 0 || broken(ret == 1) /* AMD */, "got %u\n", ret ); - todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + ok( ret == 0 || broken(ret == 1) /* AMD */, "got %u\n", ret ); + ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); pbuffer_attribs[0] = WGL_CUBE_MAP_FACE_ARB; pbuffer_attribs[1] = WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB; SetLastError( 0xdeadbeef ); ret = pwglSetPbufferAttribARB( pbuffer, pbuffer_attribs ); - todo_wine ok( ret == 0 || broken(ret == 1) /* AMD */, "got %u\n", ret ); - todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() ); + ok( ret == 0 || broken(ret == 1) /* AMD */, "got %u\n", ret ); + ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(!GetLastError()) /* AMD */, "got %#lx\n", GetLastError() );
value = 0xdeadbeef; ret = pwglQueryPbufferARB( pbuffer, WGL_PBUFFER_WIDTH_ARB, &value ); @@ -532,7 +532,7 @@ static void test_pbuffers( HDC old_hdc ) value = 0xdeadbeef; ret = pwglQueryPbufferARB( pbuffer, WGL_MIPMAP_TEXTURE_ARB, &value ); ok( ret == 1, "got %u\n", ret ); - todo_wine ok( value == 1 || broken(value > 0) /* AMD */, "got %u\n", value ); + ok( value == 1 || broken(value > 0) /* AMD */, "got %u\n", value ); value = 0xdeadbeef; ret = pwglQueryPbufferARB( pbuffer, WGL_MIPMAP_LEVEL_ARB, &value ); ok( ret == 1, "got %u\n", ret ); @@ -586,8 +586,8 @@ static void test_pbuffers( HDC old_hdc ) todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(GetLastError() == 0xdeadbeef) /* AMD */, "got %#lx\n", GetLastError() ); SetLastError( 0xdeadbeef ); ret = pwglBindTexImageARB( pbuffer, GL_BACK ); - todo_wine ok( ret == 0, "got %u\n", ret ); - todo_wine ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(GetLastError() == 0xdeadbeef) /* AMD */, "got %#lx\n", GetLastError() ); + ok( ret == 0, "got %u\n", ret ); + ok( (GetLastError() & 0xffff) == ERROR_INVALID_DATA || broken(GetLastError() == 0xdeadbeef) /* AMD */, "got %#lx\n", GetLastError() );
/* test invalid calls */ SetLastError( 0xdeadbeef ); @@ -600,13 +600,13 @@ static void test_pbuffers( HDC old_hdc ) ok( value == 0, "got %u\n", value ); value = 0xdeadbeef; glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &value ); - todo_wine ok( value == 0, "got %u\n", value ); + ok( value == 0, "got %u\n", value ); value = 0xdeadbeef; glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &value ); - todo_wine ok( value == 0, "got %u\n", value ); + ok( value == 0, "got %u\n", value ); memset( pixels, 0xcd, sizeof(pixels) ); glGetTexImage( GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels ); - todo_wine ok( pixels[0] == 0xcdcdcdcd, "got %#x\n", pixels[0] ); + ok( pixels[0] == 0xcdcdcdcd, "got %#x\n", pixels[0] ); ret = pwglReleaseTexImageARB( pbuffer, WGL_FRONT_LEFT_ARB ); ok( ret == 1 || broken(ret == 0) /* AMD */, "got %u\n", ret );
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 3498a693b2b..42f2805e594 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -50,6 +50,8 @@ struct wgl_pbuffer GLsizei height; GLenum texture_format; GLenum texture_target; + GLint mipmap_level; + GLenum cube_face;
struct wgl_context *tmp_context; struct wgl_context *prev_context; @@ -521,9 +523,9 @@ static void win32u_get_pixel_formats( struct wgl_pixel_format *formats, UINT max static struct wgl_pbuffer *win32u_wglCreatePbufferARB( HDC hdc, int format, int width, int height, const int *attribs ) { + UINT total, onscreen, size, max_level = 0; struct wgl_pbuffer *pbuffer; struct opengl_funcs *funcs; - UINT total, onscreen; BOOL largest = FALSE;
TRACE( "(%p, %d, %d, %d, %p)\n", hdc, format, width, height, attribs ); @@ -552,6 +554,7 @@ static struct wgl_pbuffer *win32u_wglCreatePbufferARB( HDC hdc, int format, int pbuffer->funcs = funcs; pbuffer->width = width; pbuffer->height = height; + pbuffer->mipmap_level = -1;
for (; attribs && attribs[0]; attribs += 2) { @@ -623,6 +626,11 @@ static struct wgl_pbuffer *win32u_wglCreatePbufferARB( HDC hdc, int format, int
case WGL_MIPMAP_TEXTURE_ARB: TRACE( "WGL_MIPMAP_TEXTURE_ARB %#x\n", attribs[1] ); + if (attribs[1]) + { + pbuffer->mipmap_level = max_level = 0; + for (size = min( width, height ) / 2; size; size /= 2) max_level++; + } break;
default: @@ -631,7 +639,8 @@ static struct wgl_pbuffer *win32u_wglCreatePbufferARB( HDC hdc, int format, int } }
- if (pbuffer->driver_funcs->p_pbuffer_create( pbuffer->hdc, format, largest, &pbuffer->width, + if (pbuffer->driver_funcs->p_pbuffer_create( pbuffer->hdc, format, largest, pbuffer->texture_format, + pbuffer->texture_target, max_level, &pbuffer->width, &pbuffer->height, &pbuffer->driver_private )) return pbuffer;
@@ -716,8 +725,34 @@ static BOOL win32u_wglQueryPbufferARB( struct wgl_pbuffer *pbuffer, int attrib, break;
case WGL_MIPMAP_TEXTURE_ARB: - *value = GL_FALSE; - FIXME( "WGL_MIPMAP_TEXTURE_ARB not supported\n" ); + *value = pbuffer->mipmap_level >= 0; + break; + case WGL_MIPMAP_LEVEL_ARB: + *value = max( pbuffer->mipmap_level, 0 ); + break; + case WGL_CUBE_MAP_FACE_ARB: + switch (pbuffer->cube_face) + { + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + default: + *value = WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB; + break; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + *value = WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB; + break; + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + *value = WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB; + break; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + *value = WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB; + break; + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + *value = WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB; + break; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + *value = WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB; + break; + } break;
default: @@ -744,8 +779,11 @@ static GLenum binding_from_target( GLenum target ) static BOOL win32u_wglBindTexImageARB( struct wgl_pbuffer *pbuffer, int buffer ) { HDC prev_draw = NtCurrentTeb()->glReserved1[0], prev_read = NtCurrentTeb()->glReserved1[1]; + int prev_texture = 0, format = win32u_wglGetPixelFormat( pbuffer->hdc ); struct wgl_context *prev_context = NtCurrentTeb()->glContext; - int prev_texture = 0; + struct wgl_pixel_format desc; + GLenum source; + UINT ret;
TRACE( "pbuffer %p, buffer %d\n", pbuffer, buffer );
@@ -755,6 +793,52 @@ static BOOL win32u_wglBindTexImageARB( struct wgl_pbuffer *pbuffer, int buffer ) return GL_FALSE; }
+ if (!pbuffer->driver_funcs->p_describe_pixel_format( format, &desc )) + { + RtlSetLastWin32Error( ERROR_INVALID_PIXEL_FORMAT ); + return FALSE; + } + + switch (buffer) + { + case WGL_FRONT_LEFT_ARB: + if (desc.pfd.dwFlags & PFD_STEREO) source = GL_FRONT_LEFT; + else source = GL_FRONT; + break; + case WGL_FRONT_RIGHT_ARB: + source = GL_FRONT_RIGHT; + break; + case WGL_BACK_LEFT_ARB: + if (desc.pfd.dwFlags & PFD_STEREO) source = GL_BACK_LEFT; + else source = GL_BACK; + break; + case WGL_BACK_RIGHT_ARB: + source = GL_BACK_RIGHT; + break; + case WGL_AUX0_ARB: source = GL_AUX0; break; + case WGL_AUX1_ARB: source = GL_AUX1; break; + case WGL_AUX2_ARB: source = GL_AUX2; break; + case WGL_AUX3_ARB: source = GL_AUX3; break; + + case WGL_AUX4_ARB: + case WGL_AUX5_ARB: + case WGL_AUX6_ARB: + case WGL_AUX7_ARB: + case WGL_AUX8_ARB: + case WGL_AUX9_ARB: + FIXME( "Unsupported source buffer %#x\n", buffer ); + RtlSetLastWin32Error( ERROR_INVALID_DATA ); + return GL_FALSE; + + default: + WARN( "Unknown source buffer %#x\n", buffer ); + RtlSetLastWin32Error( ERROR_INVALID_DATA ); + return GL_FALSE; + } + + if ((ret = pbuffer->driver_funcs->p_pbuffer_bind( pbuffer->hdc, pbuffer->driver_private, source )) != -1) + return ret; + if (!pbuffer->tmp_context || pbuffer->prev_context != prev_context) { if (pbuffer->tmp_context) pbuffer->funcs->p_wglDeleteContext( pbuffer->tmp_context ); @@ -787,7 +871,8 @@ static BOOL win32u_wglReleaseTexImageARB( struct wgl_pbuffer *pbuffer, int buffe RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); return GL_FALSE; } - return GL_TRUE; + + return !!pbuffer->driver_funcs->p_pbuffer_bind( pbuffer->hdc, pbuffer->driver_private, GL_NONE ); }
static BOOL win32u_wglSetPbufferAttribARB( struct wgl_pbuffer *pbuffer, const int *attribs ) @@ -799,7 +884,54 @@ static BOOL win32u_wglSetPbufferAttribARB( struct wgl_pbuffer *pbuffer, const in RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); return GL_FALSE; } - return GL_TRUE; + + for (; attribs && attribs[0]; attribs += 2) + { + switch (attribs[0]) + { + case WGL_MIPMAP_LEVEL_ARB: + TRACE( "WGL_MIPMAP_LEVEL_ARB %#x\n", attribs[1] ); + pbuffer->mipmap_level = attribs[1]; + break; + + case WGL_CUBE_MAP_FACE_ARB: + TRACE( "WGL_CUBE_MAP_FACE_ARB %#x\n", attribs[1] ); + switch (attribs[1]) + { + case WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: + pbuffer->cube_face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; + break; + case WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: + pbuffer->cube_face = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; + break; + case WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: + pbuffer->cube_face = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; + break; + case WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: + pbuffer->cube_face = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; + break; + case WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: + pbuffer->cube_face = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; + break; + case WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: + pbuffer->cube_face = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; + break; + default: + FIXME( "Unknown texture face: %x\n", attribs[1] ); + RtlSetLastWin32Error( ERROR_INVALID_DATA ); + return GL_FALSE; + } + break; + + default: + FIXME( "Invalid attribute 0x%x\n", attribs[0] ); + RtlSetLastWin32Error( ERROR_INVALID_DATA ); + return GL_FALSE; + } + } + + return pbuffer->driver_funcs->p_pbuffer_updated( pbuffer->hdc, pbuffer->driver_private, + pbuffer->cube_face, max( pbuffer->mipmap_level, 0 ) ); }
static void memory_funcs_init(void) diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index a9a4dc53da0..6731cb0cba3 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -67,10 +67,12 @@ struct wgl_context HWND draw_hwnd; macdrv_view draw_view; RECT draw_rect; - struct wgl_pbuffer *draw_pbuffer; + CGLPBufferObj draw_pbuffer; + GLenum draw_pbuffer_face; + GLint draw_pbuffer_level; macdrv_view read_view; RECT read_rect; - struct wgl_pbuffer *read_pbuffer; + CGLPBufferObj read_pbuffer; BOOL has_been_current; BOOL sharing; LONG update_swap_interval; @@ -82,18 +84,8 @@ struct wgl_context static struct list context_list = LIST_INIT(context_list); static pthread_mutex_t context_mutex = PTHREAD_MUTEX_INITIALIZER;
- -struct wgl_pbuffer -{ - CGLPBufferObj pbuffer; - int format; - BOOL no_texture; - int max_level; - GLint level; - GLenum face; -}; - static CFMutableDictionaryRef dc_pbuffers; +static CFMutableDictionaryRef dc_pbformats; static pthread_mutex_t dc_pbuffers_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -1544,7 +1536,7 @@ static void make_context_current(struct wgl_context *context, BOOL read) { macdrv_view view; RECT view_rect; - struct wgl_pbuffer *pbuffer; + CGLPBufferObj pbuffer;
if (read) { @@ -1569,8 +1561,7 @@ static void make_context_current(struct wgl_context *context, BOOL read)
if (CGLIsEnabled(context->cglcontext, kCGLCESurfaceBackingSize, &enabled) == kCGLNoError && enabled) CGLDisable(context->cglcontext, kCGLCESurfaceBackingSize); - CGLSetPBuffer(context->cglcontext, pbuffer->pbuffer, pbuffer->face, - pbuffer->level, 0); + CGLSetPBuffer(context->cglcontext, pbuffer, context->draw_pbuffer_face, context->draw_pbuffer_level, 0); CGLSetCurrentContext(context->cglcontext); } } @@ -2210,65 +2201,18 @@ static void macdrv_glViewport(GLint x, GLint y, GLsizei width, GLsizei height) * * WGL_ARB_render_texture: wglBindTexImageARB */ -static BOOL macdrv_wglBindTexImageARB(struct wgl_pbuffer *pbuffer, int iBuffer) +static UINT macdrv_pbuffer_bind(HDC hdc, void *private, GLenum source) { struct wgl_context *context = NtCurrentTeb()->glContext; - GLenum source; + CGLPBufferObj pbuffer = private; CGLError err;
- TRACE("pbuffer %p iBuffer 0x%x\n", pbuffer, iBuffer); + TRACE("hdc %p pbuffer %p source 0x%x\n", hdc, pbuffer, source);
- if (pbuffer->no_texture) - { - RtlSetLastWin32Error(ERROR_INVALID_OPERATION); - return GL_FALSE; - } - - if (!context->draw_view && context->draw_pbuffer == pbuffer) + if (!context->draw_view && context->draw_pbuffer == pbuffer && source != GL_NONE) opengl_funcs.p_glFlush();
- switch (iBuffer) - { - case WGL_FRONT_LEFT_ARB: - if (pixel_formats[pbuffer->format - 1].stereo) - source = GL_FRONT_LEFT; - else - source = GL_FRONT; - break; - case WGL_FRONT_RIGHT_ARB: - source = GL_FRONT_RIGHT; - break; - case WGL_BACK_LEFT_ARB: - if (pixel_formats[pbuffer->format - 1].stereo) - source = GL_BACK_LEFT; - else - source = GL_BACK; - break; - case WGL_BACK_RIGHT_ARB: - source = GL_BACK_RIGHT; - break; - case WGL_AUX0_ARB: source = GL_AUX0; break; - case WGL_AUX1_ARB: source = GL_AUX1; break; - case WGL_AUX2_ARB: source = GL_AUX2; break; - case WGL_AUX3_ARB: source = GL_AUX3; break; - - case WGL_AUX4_ARB: - case WGL_AUX5_ARB: - case WGL_AUX6_ARB: - case WGL_AUX7_ARB: - case WGL_AUX8_ARB: - case WGL_AUX9_ARB: - FIXME("unsupported source buffer 0x%x\n", iBuffer); - RtlSetLastWin32Error(ERROR_INVALID_DATA); - return GL_FALSE; - - default: - WARN("unknown source buffer 0x%x\n", iBuffer); - RtlSetLastWin32Error(ERROR_INVALID_DATA); - return GL_FALSE; - } - - err = CGLTexImagePBuffer(context->cglcontext, pbuffer->pbuffer, source); + err = CGLTexImagePBuffer(context->cglcontext, pbuffer, source); if (err != kCGLNoError) { WARN("CGLTexImagePBuffer failed with err %d %s\n", err, CGLErrorString(err)); @@ -2299,17 +2243,9 @@ static int get_dc_pixel_format(HDC hdc) } else { - struct wgl_pbuffer *pbuffer; - pthread_mutex_lock(&dc_pbuffers_mutex); - pbuffer = (struct wgl_pbuffer*)CFDictionaryGetValue(dc_pbuffers, hdc); - if (pbuffer) - format = pbuffer->format; - else - { - WARN("no window or pbuffer for DC %p\n", hdc); - format = 0; - } + format = (UINT_PTR)CFDictionaryGetValue(dc_pbformats, hdc); + if (!format) WARN("no window or pbuffer for DC %p\n", hdc); pthread_mutex_unlock(&dc_pbuffers_mutex); }
@@ -2495,191 +2431,48 @@ static struct wgl_context *macdrv_wglCreateContextAttribsARB(HDC hdc, return context; }
- -/********************************************************************** - * macdrv_wglCreatePbufferARB - * - * WGL_ARB_pbuffer: wglCreatePbufferARB - */ -static struct wgl_pbuffer *macdrv_wglCreatePbufferARB(HDC hdc, int iPixelFormat, int iWidth, int iHeight, - const int *piAttribList) +static BOOL macdrv_pbuffer_create(HDC hdc, int format, BOOL largest, GLenum texture_format, GLenum texture_target, + GLint max_level, GLsizei *width, GLsizei *height, void **private) { - struct wgl_pbuffer* pbuffer; - GLenum target = 0; - GLenum internalFormat = 0; CGLError err;
- TRACE("hdc %p iPixelFormat %d iWidth %d iHeight %d piAttribList %p\n", - hdc, iPixelFormat, iWidth, iHeight, piAttribList); - - if (!is_valid_pixel_format(iPixelFormat) || !pixel_formats[iPixelFormat - 1].pbuffer) - { - WARN("invalid pixel format %d\n", iPixelFormat); - RtlSetLastWin32Error(ERROR_INVALID_PIXEL_FORMAT); - return NULL; - } - - pbuffer = calloc(1, sizeof(*pbuffer)); - pbuffer->format = iPixelFormat; - - for ( ; piAttribList && *piAttribList; piAttribList += 2) - { - int attr = piAttribList[0]; - int value = piAttribList[1]; - - switch (attr) - { - case WGL_PBUFFER_LARGEST_ARB: - FIXME("WGL_PBUFFER_LARGEST_ARB: %d; ignoring\n", value); - break; - - case WGL_TEXTURE_FORMAT_ARB: - switch (value) - { - case WGL_TEXTURE_RGBA_ARB: - TRACE("WGL_TEXTURE_FORMAT_ARB: WGL_TEXTURE_RGBA_ARB\n"); - internalFormat = GL_RGBA; - break; - case WGL_TEXTURE_RGB_ARB: - TRACE("WGL_TEXTURE_FORMAT_ARB: WGL_TEXTURE_RGB_ARB\n"); - internalFormat = GL_RGB; - break; - case WGL_NO_TEXTURE_ARB: - TRACE("WGL_TEXTURE_FORMAT_ARB: WGL_NO_TEXTURE_ARB\n"); - internalFormat = 0; - break; - default: - WARN("unknown WGL_TEXTURE_FORMAT_ARB value 0x%x\n", value); - RtlSetLastWin32Error(ERROR_INVALID_DATA); - goto done; - } - break; - - case WGL_TEXTURE_TARGET_ARB: - pbuffer->face = 0; - switch (value) - { - case WGL_NO_TEXTURE_ARB: - TRACE("WGL_TEXTURE_TARGET_ARB: WGL_NO_TEXTURE_ARB\n"); - target = 0; - break; - case WGL_TEXTURE_CUBE_MAP_ARB: - TRACE("WGL_TEXTURE_TARGET_ARB: WGL_TEXTURE_CUBE_MAP_ARB\n"); - target = GL_TEXTURE_CUBE_MAP; - pbuffer->face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; - break; - case WGL_TEXTURE_1D_ARB: - FIXME("WGL_TEXTURE_TARGET_ARB: WGL_TEXTURE_1D_ARB; not supported\n"); - RtlSetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); - goto done; - case WGL_TEXTURE_2D_ARB: - TRACE("WGL_TEXTURE_TARGET_ARB: WGL_TEXTURE_2D_ARB\n"); - target = GL_TEXTURE_2D; - break; - case WGL_TEXTURE_RECTANGLE_NV: - TRACE("WGL_TEXTURE_TARGET_ARB: WGL_TEXTURE_RECTANGLE_NV\n"); - target = GL_TEXTURE_RECTANGLE; - break; - default: - WARN("unknown WGL_TEXTURE_TARGET_ARB value 0x%x\n", value); - RtlSetLastWin32Error(ERROR_INVALID_DATA); - goto done; - } - break; - - case WGL_MIPMAP_TEXTURE_ARB: - TRACE("WGL_MIPMAP_TEXTURE_ARB: %d\n", value); - pbuffer->max_level = 0; - if (value) - { - int size = min(iWidth, iHeight) / 2; - while (size) - { - pbuffer->max_level++; - size /= 2; - } - } - break; - - default: - WARN("unknown attribute 0x%x\n", attr); - RtlSetLastWin32Error(ERROR_INVALID_DATA); - goto done; - } - } + TRACE("hdc %p, format %d, largest %u, texture_format %#x, texture_target %#x, max_level %#x, width %d, height %d, private %p\n", + hdc, format, largest, texture_format, texture_target, max_level, *width, *height, private);
- if (!target || !internalFormat) + if (!texture_target || !texture_format) { - pbuffer->no_texture = TRUE; /* no actual way to turn off ability to texture; use most permissive target */ - target = GL_TEXTURE_RECTANGLE; - internalFormat = GL_RGB; + texture_target = GL_TEXTURE_RECTANGLE; + texture_format = GL_RGB; }
- err = CGLCreatePBuffer(iWidth, iHeight, target, internalFormat, pbuffer->max_level, &pbuffer->pbuffer); + err = CGLCreatePBuffer(*width, *height, texture_target, texture_format, max_level, (CGLPBufferObj *)private); if (err != kCGLNoError) { WARN("CGLCreatePBuffer failed; err %d %s\n", err, CGLErrorString(err)); - pbuffer->pbuffer = NULL; - if (err == kCGLBadAlloc) - RtlSetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); - else - RtlSetLastWin32Error(ERROR_INVALID_DATA); - } - -done: - if (!pbuffer->pbuffer) - { - free(pbuffer); - return NULL; + return FALSE; }
- TRACE(" -> %p\n", pbuffer); - return pbuffer; -} - + pthread_mutex_lock(&dc_pbuffers_mutex); + CFDictionarySetValue(dc_pbuffers, hdc, private); + CFDictionarySetValue(dc_pbformats, hdc, (void *)(UINT_PTR)format); + pthread_mutex_unlock(&dc_pbuffers_mutex);
-/********************************************************************** - * macdrv_wglDestroyPbufferARB - * - * WGL_ARB_pbuffer: wglDestroyPbufferARB - */ -static BOOL macdrv_wglDestroyPbufferARB(struct wgl_pbuffer *pbuffer) -{ - TRACE("pbuffer %p\n", pbuffer); - if (pbuffer && pbuffer->pbuffer) - CGLReleasePBuffer(pbuffer->pbuffer); - free(pbuffer); - return GL_TRUE; + TRACE(" -> %p\n", *private); + return TRUE; }
- -/********************************************************************** - * macdrv_wglGetPbufferDCARB - * - * WGL_ARB_pbuffer: wglGetPbufferDCARB - */ -static HDC macdrv_wglGetPbufferDCARB(struct wgl_pbuffer *pbuffer) +static BOOL macdrv_pbuffer_destroy(HDC hdc, void *private) { - HDC hdc; - struct wgl_pbuffer *prev; - - hdc = NtGdiOpenDCW(NULL, NULL, NULL, 0, TRUE, NULL, NULL, NULL); - if (!hdc) return 0; + TRACE("private %p\n", private);
pthread_mutex_lock(&dc_pbuffers_mutex); - prev = (struct wgl_pbuffer*)CFDictionaryGetValue(dc_pbuffers, hdc); - if (prev) - { - CGLReleasePBuffer(prev->pbuffer); - free(prev); - } - CFDictionarySetValue(dc_pbuffers, hdc, pbuffer); + CFDictionaryRemoveValue(dc_pbuffers, hdc); + CFDictionaryRemoveValue(dc_pbformats, hdc); pthread_mutex_unlock(&dc_pbuffers_mutex);
- NtGdiSetPixelFormat(hdc, pbuffer->format); - TRACE("pbuffer %p -> hdc %p\n", pbuffer, hdc); - return hdc; + CGLReleasePBuffer(private); + return GL_TRUE; }
@@ -2780,15 +2573,16 @@ static BOOL macdrv_wglMakeContextCurrentARB(HDC draw_hdc, HDC read_hdc, struct w } else { - struct wgl_pbuffer *pbuffer; + CGLPBufferObj pbuffer;
pthread_mutex_lock(&dc_pbuffers_mutex); - pbuffer = (struct wgl_pbuffer*)CFDictionaryGetValue(dc_pbuffers, draw_hdc); + pbuffer = (CGLPBufferObj)CFDictionaryGetValue(dc_pbuffers, draw_hdc); if (pbuffer) { - if (context->format != pbuffer->format) + int format = (UINT_PTR)CFDictionaryGetValue(dc_pbformats, draw_hdc); + if (context->format != format) { - WARN("mismatched pixel format draw_hdc %p %u context %p %u\n", draw_hdc, pbuffer->format, context, context->format); + WARN("mismatched pixel format draw_hdc %p %u context %p %u\n", draw_hdc, format, context, context->format); pthread_mutex_unlock(&dc_pbuffers_mutex); RtlSetLastWin32Error(ERROR_INVALID_PIXEL_FORMAT); return FALSE; @@ -2831,7 +2625,7 @@ static BOOL macdrv_wglMakeContextCurrentARB(HDC draw_hdc, HDC read_hdc, struct w else { pthread_mutex_lock(&dc_pbuffers_mutex); - context->read_pbuffer = (struct wgl_pbuffer*)CFDictionaryGetValue(dc_pbuffers, read_hdc); + context->read_pbuffer = (CGLPBufferObj)CFDictionaryGetValue(dc_pbuffers, read_hdc); pthread_mutex_unlock(&dc_pbuffers_mutex); } } @@ -2966,113 +2760,6 @@ static const char *macdrv_wglQueryCurrentRendererStringWINE(GLenum attribute) }
-/********************************************************************** - * macdrv_wglQueryPbufferARB - * - * WGL_ARB_pbuffer: wglQueryPbufferARB - */ -static BOOL macdrv_wglQueryPbufferARB(struct wgl_pbuffer *pbuffer, int iAttribute, int *piValue) -{ - CGLError err; - GLsizei width; - GLsizei height; - GLenum target; - GLenum internalFormat; - GLint mipmap; - - TRACE("pbuffer %p iAttribute 0x%x piValue %p\n", pbuffer, iAttribute, piValue); - - err = CGLDescribePBuffer(pbuffer->pbuffer, &width, &height, &target, &internalFormat, &mipmap); - if (err != kCGLNoError) - { - WARN("CGLDescribePBuffer failed; error %d %s\n", err, CGLErrorString(err)); - RtlSetLastWin32Error(ERROR_INVALID_HANDLE); - return GL_FALSE; - } - - switch (iAttribute) - { - case WGL_PBUFFER_WIDTH_ARB: - *piValue = width; - break; - case WGL_PBUFFER_HEIGHT_ARB: - *piValue = height; - break; - case WGL_PBUFFER_LOST_ARB: - /* Mac PBuffers can't be lost */ - *piValue = GL_FALSE; - break; - case WGL_TEXTURE_FORMAT_ARB: - if (pbuffer->no_texture) - *piValue = WGL_NO_TEXTURE_ARB; - else switch (internalFormat) - { - case GL_RGBA: - *piValue = WGL_TEXTURE_RGBA_ARB; - break; - case GL_RGB: - default: - *piValue = WGL_TEXTURE_RGB_ARB; - break; - } - break; - case WGL_TEXTURE_TARGET_ARB: - if (pbuffer->no_texture) - *piValue = WGL_NO_TEXTURE_ARB; - else switch (target) - { - case GL_TEXTURE_CUBE_MAP: - *piValue = WGL_TEXTURE_CUBE_MAP_ARB; - break; - case GL_TEXTURE_2D: - *piValue = WGL_TEXTURE_2D_ARB; - break; - case GL_TEXTURE_RECTANGLE: - default: - *piValue = WGL_TEXTURE_RECTANGLE_NV; - break; - } - break; - case WGL_MIPMAP_TEXTURE_ARB: - *piValue = (pbuffer->max_level > 0); - break; - case WGL_MIPMAP_LEVEL_ARB: - *piValue = pbuffer->level; - break; - case WGL_CUBE_MAP_FACE_ARB: - switch (pbuffer->face) - { - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - default: - *piValue = WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB; - break; - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - *piValue = WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB; - break; - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - *piValue = WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB; - break; - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - *piValue = WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB; - break; - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - *piValue = WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB; - break; - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - *piValue = WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB; - break; - } - break; - default: - WARN("invalid attribute 0x%x\n", iAttribute); - RtlSetLastWin32Error(ERROR_INVALID_DATA); - return GL_FALSE; - } - - return GL_TRUE; -} - - /********************************************************************** * macdrv_wglQueryRendererIntegerWINE * @@ -3166,129 +2853,19 @@ done: }
-/********************************************************************** - * macdrv_wglReleasePbufferDCARB - * - * WGL_ARB_pbuffer: wglReleasePbufferDCARB - */ -static int macdrv_wglReleasePbufferDCARB(struct wgl_pbuffer *pbuffer, HDC hdc) -{ - struct wgl_pbuffer *prev; - - TRACE("pbuffer %p hdc %p\n", pbuffer, hdc); - - pthread_mutex_lock(&dc_pbuffers_mutex); - - prev = (struct wgl_pbuffer*)CFDictionaryGetValue(dc_pbuffers, hdc); - if (prev) - { - if (prev != pbuffer) - FIXME("hdc %p isn't associated with pbuffer %p\n", hdc, pbuffer); - CGLReleasePBuffer(prev->pbuffer); - free(prev); - CFDictionaryRemoveValue(dc_pbuffers, hdc); - } - else hdc = 0; - - pthread_mutex_unlock(&dc_pbuffers_mutex); - - return hdc && NtGdiDeleteObjectApp(hdc); -} - - -/********************************************************************** - * macdrv_wglReleaseTexImageARB - * - * WGL_ARB_render_texture: wglReleaseTexImageARB - */ -static BOOL macdrv_wglReleaseTexImageARB(struct wgl_pbuffer *pbuffer, int iBuffer) -{ - struct wgl_context *context = NtCurrentTeb()->glContext; - CGLError err; - - TRACE("pbuffer %p iBuffer 0x%x; stub!\n", pbuffer, iBuffer); - - if (pbuffer->no_texture) - { - RtlSetLastWin32Error(ERROR_INVALID_OPERATION); - return GL_FALSE; - } - - err = CGLTexImagePBuffer(context->cglcontext, pbuffer->pbuffer, GL_NONE); - if (err != kCGLNoError) - { - WARN("CGLTexImagePBuffer failed with err %d %s\n", err, CGLErrorString(err)); - RtlSetLastWin32Error(ERROR_INVALID_OPERATION); - return GL_FALSE; - } - - return GL_TRUE; -} - - -/********************************************************************** - * macdrv_wglSetPbufferAttribARB - * - * WGL_ARB_render_texture: wglSetPbufferAttribARB - */ -static BOOL macdrv_wglSetPbufferAttribARB(struct wgl_pbuffer *pbuffer, const int *piAttribList) +static BOOL macdrv_pbuffer_updated(HDC hdc, void *private, GLenum cube_face, GLint mipmap_level) { struct wgl_context *context = NtCurrentTeb()->glContext; + CGLPBufferObj pbuffer = private;
- TRACE("pbuffer %p piAttribList %p\n", pbuffer, piAttribList); - - for ( ; piAttribList && *piAttribList; piAttribList += 2) - { - int attr = piAttribList[0]; - int value = piAttribList[1]; - switch (attr) - { - case WGL_MIPMAP_LEVEL_ARB: - TRACE("WGL_MIPMAP_LEVEL_ARB: %d\n", value); - pbuffer->level = value; - break; - case WGL_CUBE_MAP_FACE_ARB: - switch (value) - { - case WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: - TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB\n"); - pbuffer->face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; - break; - case WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: - TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB\n"); - pbuffer->face = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; - break; - case WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: - TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB\n"); - pbuffer->face = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; - break; - case WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: - TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB\n"); - pbuffer->face = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; - break; - case WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: - TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB\n"); - pbuffer->face = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; - break; - case WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: - TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB\n"); - pbuffer->face = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; - break; - default: - WARN("unknown WGL_CUBE_MAP_FACE_ARB value 0x%x\n", value); - RtlSetLastWin32Error(ERROR_INVALID_DATA); - return GL_FALSE; - } - break; - default: - WARN("invalid attribute 0x%x\n", attr); - RtlSetLastWin32Error(ERROR_INVALID_DATA); - return GL_FALSE; - } - } + TRACE("hdc %p pbuffer %p cube_face %#x mipmap_level %d\n", hdc, pbuffer, cube_face, mipmap_level);
if (context && context->draw_pbuffer == pbuffer) + { + context->draw_pbuffer_face = cube_face; + context->draw_pbuffer_level = mipmap_level; make_context_current(context, FALSE); + }
return GL_TRUE; } @@ -3387,18 +2964,6 @@ static const char *macdrv_init_wgl_extensions(void)
if (gluCheckExtension((GLubyte*)"GL_APPLE_pixel_buffer", (GLubyte*)gl_info.glExtensions)) { - register_extension("WGL_ARB_pbuffer"); - opengl_funcs.p_wglCreatePbufferARB = macdrv_wglCreatePbufferARB; - opengl_funcs.p_wglDestroyPbufferARB = macdrv_wglDestroyPbufferARB; - opengl_funcs.p_wglGetPbufferDCARB = macdrv_wglGetPbufferDCARB; - opengl_funcs.p_wglQueryPbufferARB = macdrv_wglQueryPbufferARB; - opengl_funcs.p_wglReleasePbufferDCARB = macdrv_wglReleasePbufferDCARB; - - register_extension("WGL_ARB_render_texture"); - opengl_funcs.p_wglBindTexImageARB = macdrv_wglBindTexImageARB; - opengl_funcs.p_wglReleaseTexImageARB = macdrv_wglReleaseTexImageARB; - opengl_funcs.p_wglSetPbufferAttribARB = macdrv_wglSetPbufferAttribARB; - if (gluCheckExtension((GLubyte*)"GL_ARB_texture_rectangle", (GLubyte*)gl_info.glExtensions) || gluCheckExtension((GLubyte*)"GL_EXT_texture_rectangle", (GLubyte*)gl_info.glExtensions)) register_extension("WGL_NV_render_texture_rectangle"); @@ -3453,7 +3018,8 @@ UINT macdrv_OpenGLInit(UINT version, struct opengl_funcs **funcs, const struct o }
dc_pbuffers = CFDictionaryCreateMutable(NULL, 0, NULL, NULL); - if (!dc_pbuffers) + dc_pbformats = CFDictionaryCreateMutable(NULL, 0, NULL, NULL); + if (!dc_pbuffers || !dc_pbformats) { WARN("CFDictionaryCreateMutable failed\n"); return STATUS_NOT_SUPPORTED; @@ -3794,10 +3360,10 @@ static BOOL macdrv_wglSwapBuffers(HDC hdc) } else { - struct wgl_pbuffer *pbuffer; + CGLPBufferObj pbuffer;
pthread_mutex_lock(&dc_pbuffers_mutex); - pbuffer = (struct wgl_pbuffer*)CFDictionaryGetValue(dc_pbuffers, hdc); + pbuffer = (CGLPBufferObj)CFDictionaryGetValue(dc_pbuffers, hdc); pthread_mutex_unlock(&dc_pbuffers_mutex);
if (!pbuffer) @@ -3832,6 +3398,10 @@ static const struct opengl_driver_funcs macdrv_driver_funcs = .p_describe_pixel_format = macdrv_describe_pixel_format, .p_init_wgl_extensions = macdrv_init_wgl_extensions, .p_set_pixel_format = macdrv_set_pixel_format, + .p_pbuffer_create = macdrv_pbuffer_create, + .p_pbuffer_destroy = macdrv_pbuffer_destroy, + .p_pbuffer_updated = macdrv_pbuffer_updated, + .p_pbuffer_bind = macdrv_pbuffer_bind, };
static struct opengl_funcs opengl_funcs = diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index cb15846ae53..cc595f87252 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -663,11 +663,13 @@ static BOOL wayland_wglSwapIntervalEXT(int interval) return ret; }
-static BOOL wayland_pbuffer_create(HDC hdc, int format, BOOL largest, int *width, int *height, void **private) +static BOOL wayland_pbuffer_create(HDC hdc, int format, BOOL largest, GLenum texture_format, GLenum texture_target, + GLint max_level, GLsizei *width, GLsizei *height, void **private) { struct wayland_gl_drawable *drawable;
- TRACE("hdc %p, format %d, largest %u, width %d, height %d, private %p\n", hdc, format, largest, *width, *height, private); + TRACE("hdc %p, format %d, largest %u, texture_format %#x, texture_target %#x, max_level %#x, width %d, height %d, private %p\n", + hdc, format, largest, texture_format, texture_target, max_level, *width, *height, private);
/* Use an unmapped wayland surface as our offscreen "pbuffer" surface. */ if (!(drawable = wayland_gl_drawable_create(0, hdc, format, *width, *height))) return FALSE; @@ -695,6 +697,18 @@ static BOOL wayland_pbuffer_destroy(HDC hdc, void *private) return GL_TRUE; }
+static BOOL wayland_pbuffer_updated(HDC hdc, void *private, GLenum cube_face, GLint mipmap_level) +{ + TRACE("hdc %p, private %p, cube_face %#x, mipmap_level %d\n", hdc, private, cube_face, mipmap_level); + return GL_TRUE; +} + +static UINT wayland_pbuffer_bind(HDC hdc, void *private, GLenum buffer) +{ + TRACE("hdc %p, private %p, buffer %#x\n", hdc, private, buffer); + return -1; /* use default implementation */ +} + static BOOL describe_pixel_format(EGLConfig config, struct wgl_pixel_format *fmt, BOOL pbuffer_single) { EGLint value, surface_type; @@ -960,6 +974,8 @@ static const struct opengl_driver_funcs wayland_driver_funcs = .p_set_pixel_format = wayland_set_pixel_format, .p_pbuffer_create = wayland_pbuffer_create, .p_pbuffer_destroy = wayland_pbuffer_destroy, + .p_pbuffer_updated = wayland_pbuffer_updated, + .p_pbuffer_bind = wayland_pbuffer_bind, };
/********************************************************************** diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 5b100659630..05ae284761c 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -1940,14 +1940,16 @@ static struct wgl_context *X11DRV_wglCreateContextAttribsARB( HDC hdc, struct wg return ret; }
-static BOOL x11drv_pbuffer_create( HDC hdc, int format, BOOL largest, int *width, int *height, void **private ) +static BOOL x11drv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum texture_format, GLenum texture_target, + GLint max_level, GLsizei *width, GLsizei *height, void **private ) { const struct glx_pixel_format *fmt; int glx_attribs[7], count = 0; struct gl_drawable *surface; RECT rect;
- TRACE( "hdc %p, format %d, largest %u, width %d, height %d, private %p\n", hdc, format, largest, *width, *height, private ); + TRACE( "hdc %p, format %d, largest %u, texture_format %#x, texture_target %#x, max_level %#x, width %d, height %d, private %p\n", + hdc, format, largest, texture_format, texture_target, max_level, *width, *height, private );
/* Convert the WGL pixelformat to a GLX format, if it fails then the format is invalid */ if (!(fmt = get_pixel_format( gdi_display, format, TRUE /* Offscreen */ ))) @@ -2006,6 +2008,18 @@ static BOOL x11drv_pbuffer_destroy( HDC hdc, void *private ) return GL_TRUE; }
+static BOOL x11drv_pbuffer_updated( HDC hdc, void *private, GLenum cube_face, GLint mipmap_level ) +{ + TRACE( "hdc %p, private %p, cube_face %#x, mipmap_level %d\n", hdc, private, cube_face, mipmap_level ); + return GL_TRUE; +} + +static UINT x11drv_pbuffer_bind( HDC hdc, void *private, GLenum buffer ) +{ + TRACE( "hdc %p, private %p, buffer %#x\n", hdc, private, buffer ); + return -1; /* use default implementation */ +} + /** * X11DRV_wglGetSwapIntervalEXT * @@ -2301,6 +2315,8 @@ static const struct opengl_driver_funcs x11drv_driver_funcs = .p_set_pixel_format = x11drv_set_pixel_format, .p_pbuffer_create = x11drv_pbuffer_create, .p_pbuffer_destroy = x11drv_pbuffer_destroy, + .p_pbuffer_updated = x11drv_pbuffer_updated, + .p_pbuffer_bind = x11drv_pbuffer_bind, };
static struct opengl_funcs opengl_funcs = diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 11bcbe6758a..1d78ac09b1c 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -118,8 +118,10 @@ struct opengl_driver_funcs const char *(*p_init_wgl_extensions)(void); BOOL (*p_set_pixel_format)(HWND,int,int,BOOL);
- BOOL (*p_pbuffer_create)(HDC,int,BOOL,GLsizei*,GLsizei*,void **); + BOOL (*p_pbuffer_create)(HDC,int,BOOL,GLenum,GLenum,GLint,GLsizei*,GLsizei*,void **); BOOL (*p_pbuffer_destroy)(HDC,void*); + BOOL (*p_pbuffer_updated)(HDC,void*,GLenum,GLint); + UINT (*p_pbuffer_bind)(HDC,void*,GLenum); };
#endif /* WINE_UNIX_LIB */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 50 +++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 14 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 42f2805e594..fc67e2c4fb0 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -418,12 +418,37 @@ static BOOL nulldrv_set_pixel_format( HWND hwnd, int old_format, int new_format, return TRUE; }
+static BOOL nulldrv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum texture_format, GLenum texture_target, + GLint max_level, GLsizei *width, GLsizei *height, void **private ) +{ + return FALSE; +} + +static BOOL nulldrv_pbuffer_destroy( HDC hdc, void *private ) +{ + return FALSE; +} + +static BOOL nulldrv_pbuffer_updated( HDC hdc, void *private, GLenum cube_face, GLint mipmap_level ) +{ + return GL_TRUE; +} + +static UINT nulldrv_pbuffer_bind( HDC hdc, void *private, GLenum buffer ) +{ + return -1; /* use default implementation */ +} + static const struct opengl_driver_funcs nulldrv_funcs = { .p_init_pixel_formats = nulldrv_init_pixel_formats, .p_describe_pixel_format = nulldrv_describe_pixel_format, .p_init_wgl_extensions = nulldrv_init_wgl_extensions, .p_set_pixel_format = nulldrv_set_pixel_format, + .p_pbuffer_create = nulldrv_pbuffer_create, + .p_pbuffer_destroy = nulldrv_pbuffer_destroy, + .p_pbuffer_updated = nulldrv_pbuffer_updated, + .p_pbuffer_bind = nulldrv_pbuffer_bind, }; static const struct opengl_driver_funcs *driver_funcs = &nulldrv_funcs; static UINT formats_count, onscreen_count; @@ -979,20 +1004,17 @@ static void display_funcs_init(void) display_funcs->p_wglGetPixelFormatAttribfvARB = (void *)1; /* never called */ display_funcs->p_wglGetPixelFormatAttribivARB = (void *)1; /* never called */
- if (driver_funcs->p_pbuffer_create) - { - register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_pbuffer" ); - display_funcs->p_wglCreatePbufferARB = win32u_wglCreatePbufferARB; - display_funcs->p_wglDestroyPbufferARB = win32u_wglDestroyPbufferARB; - display_funcs->p_wglGetPbufferDCARB = win32u_wglGetPbufferDCARB; - display_funcs->p_wglReleasePbufferDCARB = win32u_wglReleasePbufferDCARB; - display_funcs->p_wglQueryPbufferARB = win32u_wglQueryPbufferARB; - - register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_render_texture" ); - display_funcs->p_wglBindTexImageARB = win32u_wglBindTexImageARB; - display_funcs->p_wglReleaseTexImageARB = win32u_wglReleaseTexImageARB; - display_funcs->p_wglSetPbufferAttribARB = win32u_wglSetPbufferAttribARB; - } + register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_pbuffer" ); + display_funcs->p_wglCreatePbufferARB = win32u_wglCreatePbufferARB; + display_funcs->p_wglDestroyPbufferARB = win32u_wglDestroyPbufferARB; + display_funcs->p_wglGetPbufferDCARB = win32u_wglGetPbufferDCARB; + display_funcs->p_wglReleasePbufferDCARB = win32u_wglReleasePbufferDCARB; + display_funcs->p_wglQueryPbufferARB = win32u_wglQueryPbufferARB; + + register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_render_texture" ); + display_funcs->p_wglBindTexImageARB = win32u_wglBindTexImageARB; + display_funcs->p_wglReleaseTexImageARB = win32u_wglReleaseTexImageARB; + display_funcs->p_wglSetPbufferAttribARB = win32u_wglSetPbufferAttribARB; }
static struct opengl_funcs *get_dc_funcs( HDC hdc, void *null_funcs )
v3: Fix macOS build.