Used with nulldrv only for now, laying ground for framebuffer hooking in opengl32.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/driver.c | 29 +++++++++++++++++++++++++++++ dlls/win32u/opengl.c | 6 +++++- dlls/win32u/vulkan.c | 28 +--------------------------- dlls/win32u/win32u_private.h | 2 ++ 4 files changed, 37 insertions(+), 28 deletions(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index cf3be4be949..386100c0e36 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -1428,3 +1428,32 @@ INT WINAPI NtGdiExtEscape( HDC hdc, WCHAR *driver, int driver_id, INT escape, IN release_dc_ptr( dc ); return ret; } + +static void nulldrv_surface_destroy( struct client_surface *client ) +{ +} + +static void nulldrv_surface_detach( struct client_surface *client ) +{ +} + +static void nulldrv_surface_update( struct client_surface *client ) +{ +} + +static void nulldrv_surface_present( struct client_surface *client, HDC hdc ) +{ +} + +static const struct client_surface_funcs nulldrv_surface_funcs = +{ + .destroy = nulldrv_surface_destroy, + .detach = nulldrv_surface_detach, + .update = nulldrv_surface_update, + .present = nulldrv_surface_present, +}; + +struct client_surface *nulldrv_client_surface_create( HWND hwnd ) +{ + return client_surface_create( sizeof(struct client_surface), &nulldrv_surface_funcs, hwnd ); +} diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index eea6c3f3ec5..4b7fa14c6a9 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -389,7 +389,11 @@ static const char *egldrv_init_wgl_extensions( struct opengl_funcs *funcs )
static BOOL egldrv_surface_create( HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable ) { - *drawable = opengl_drawable_create( sizeof(**drawable), &egldrv_surface_funcs, format, NULL ); + struct client_surface *client; + + if (!(client = nulldrv_client_surface_create( hwnd ))) return FALSE; + *drawable = opengl_drawable_create( sizeof(**drawable), &egldrv_surface_funcs, format, client ); + client_surface_release( client ); return !!*drawable; }
diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index 722bdd845cf..0945772fb03 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -499,15 +499,13 @@ static struct vulkan_funcs vulkan_funcs = .p_get_host_surface_extension = win32u_get_host_surface_extension, };
-static const struct client_surface_funcs nulldrv_vulkan_surface_funcs; - static VkResult nulldrv_vulkan_surface_create( HWND hwnd, const struct vulkan_instance *instance, VkSurfaceKHR *surface, struct client_surface **client ) { VkHeadlessSurfaceCreateInfoEXT create_info = {.sType = VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT}; VkResult res;
- if (!(*client = client_surface_create(sizeof(**client), &nulldrv_vulkan_surface_funcs, hwnd))) return VK_ERROR_OUT_OF_HOST_MEMORY; + if (!(*client = nulldrv_client_surface_create( hwnd ))) return VK_ERROR_OUT_OF_HOST_MEMORY; if ((res = instance->p_vkCreateHeadlessSurfaceEXT( instance->host.instance, &create_info, NULL, surface ))) { client_surface_release(*client); @@ -517,22 +515,6 @@ static VkResult nulldrv_vulkan_surface_create( HWND hwnd, const struct vulkan_in return res; }
-static void nulldrv_vulkan_surface_destroy( struct client_surface *client ) -{ -} - -static void nulldrv_vulkan_surface_detach( struct client_surface *client ) -{ -} - -static void nulldrv_vulkan_surface_update( struct client_surface *client ) -{ -} - -static void nulldrv_vulkan_surface_present( struct client_surface *client, HDC hdc ) -{ -} - static VkBool32 nulldrv_vkGetPhysicalDeviceWin32PresentationSupportKHR( VkPhysicalDevice device, uint32_t queue ) { return VK_TRUE; @@ -543,14 +525,6 @@ static const char *nulldrv_get_host_surface_extension(void) return "VK_EXT_headless_surface"; }
-static const struct client_surface_funcs nulldrv_vulkan_surface_funcs = -{ - .destroy = nulldrv_vulkan_surface_destroy, - .detach = nulldrv_vulkan_surface_detach, - .update = nulldrv_vulkan_surface_update, - .present = nulldrv_vulkan_surface_present, -}; - static const struct vulkan_driver_funcs nulldrv_funcs = { .p_vulkan_surface_create = nulldrv_vulkan_surface_create, diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index e683f7cd824..9e7eed4584c 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -325,7 +325,9 @@ extern void reg_delete_value( HKEY hkey, const WCHAR *name );
extern HKEY hkcu_key;
+/* driver.c */ extern const struct user_driver_funcs *user_driver; +extern struct client_surface *nulldrv_client_surface_create( HWND hwnd );
extern ULONG_PTR zero_bits;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 188 ++++++++++++++++++++++++++++++----- include/wine/opengl_driver.h | 1 + 2 files changed, 162 insertions(+), 27 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 4b7fa14c6a9..212faed4eb6 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -61,6 +61,7 @@ struct wgl_pbuffer GLenum cube_face; };
+static const struct opengl_driver_funcs nulldrv_funcs, *driver_funcs = &nulldrv_funcs; static const struct opengl_funcs *default_funcs; /* default GL function table from opengl32 */ static struct egl_platform display_egl; static struct opengl_funcs display_funcs; @@ -165,9 +166,156 @@ static void opengl_drawable_flush( struct opengl_drawable *drawable, int interva drawable->funcs->flush( drawable, flags ); }
+struct framebuffer_surface +{ + struct opengl_drawable base; +}; + +static GLenum color_format_from_pfd( const struct wgl_pixel_format *desc ) +{ + TRACE( "format type %u bits %u/%u/%u/%u\n", desc->pixel_type, desc->pfd.cRedBits, + desc->pfd.cGreenBits, desc->pfd.cBlueBits, desc->pfd.cAlphaBits ); + + if (desc->pixel_type == WGL_TYPE_RGBA_FLOAT_ARB) + { + if (desc->pfd.cAlphaBits == 32) return GL_RGBA32F; + if (desc->pfd.cAlphaBits == 16) return GL_RGBA16F; + if (desc->pfd.cBlueBits == 32) return GL_RGB32F; + if (desc->pfd.cBlueBits == 16) return GL_RGB16F; + if (desc->pfd.cGreenBits == 32) return GL_RG32F; + if (desc->pfd.cGreenBits == 16) return GL_RG16F; + if (desc->pfd.cRedBits == 32) return GL_R32F; + if (desc->pfd.cRedBits == 16) return GL_R16F; + } + else + { + if (desc->pfd.cBlueBits == 10 && desc->pfd.cGreenBits == 10 && + desc->pfd.cRedBits == 10 && desc->pfd.cAlphaBits == 2) + return GL_RGB10_A2; + if (desc->pfd.cAlphaBits == 32) return GL_RGBA32UI; + if (desc->pfd.cAlphaBits == 16) return GL_RGBA16; + if (desc->pfd.cAlphaBits == 8) return GL_RGBA8; + if (desc->pfd.cAlphaBits == 4) return GL_RGBA4; + if (desc->pfd.cBlueBits == 32) return GL_RGB32UI; + if (desc->pfd.cBlueBits == 16) return GL_RGB16; + if (desc->pfd.cBlueBits == 8) return GL_RGB8; + if (desc->pfd.cBlueBits == 4) return GL_RGB4; + if (desc->pfd.cGreenBits == 32) return GL_RG32UI; + if (desc->pfd.cGreenBits == 16) return GL_RG16; + if (desc->pfd.cGreenBits == 8) return GL_RG8; + if (desc->pfd.cRedBits == 32) return GL_R32UI; + if (desc->pfd.cRedBits == 16) return GL_R16; + if (desc->pfd.cRedBits == 8) return GL_R8; + } + + FIXME( "Unsupported format type %u bits %u/%u/%u/%u\n", desc->pixel_type, desc->pfd.cRedBits, + desc->pfd.cGreenBits, desc->pfd.cBlueBits, desc->pfd.cAlphaBits ); + return 0; +} + +static GLuint create_framebuffer( struct opengl_drawable *drawable, const struct wgl_pixel_format *desc ) +{ + const struct opengl_funcs *funcs = &display_funcs; + GLuint fbo, name; + + funcs->p_glCreateFramebuffers( 1, &fbo ); + funcs->p_glCreateRenderbuffers( 1, &name ); + funcs->p_glNamedFramebufferRenderbuffer( fbo, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, name ); + TRACE( "drawable %p/%u created color buffer %#x/%u\n", drawable, fbo, GL_COLOR_ATTACHMENT0, name ); + + funcs->p_glNamedFramebufferDrawBuffer( fbo, GL_COLOR_ATTACHMENT0 ); + funcs->p_glNamedFramebufferReadBuffer( fbo, GL_COLOR_ATTACHMENT0 ); + TRACE( "drawable %p created framebuffer %u\n", drawable, fbo ); + + return fbo; +} + +static void resize_framebuffer( struct opengl_drawable *drawable, const struct wgl_pixel_format *desc, GLuint fbo, + int width, int height ) +{ + const struct opengl_funcs *funcs = &display_funcs; + GLuint name; + GLenum ret; + + funcs->p_glGetNamedFramebufferAttachmentParameteriv( fbo, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&name ); + funcs->p_glNamedRenderbufferStorageMultisample( name, desc->samples, color_format_from_pfd( desc ), width, height ); + TRACE( "drawable %p/%u resized color buffer %#x/%u to %d,%d\n", drawable, fbo, GL_COLOR_ATTACHMENT0, name, width, height ); + + ret = funcs->p_glCheckNamedFramebufferStatus( fbo, GL_FRAMEBUFFER ); + if (ret != GL_FRAMEBUFFER_COMPLETE) WARN( "glCheckNamedFramebufferStatus returned %#x\n", ret ); + TRACE( "drawable %p/%u resized buffers to %d,%d\n", drawable, fbo, width, height ); +} + +static void destroy_framebuffer( struct opengl_drawable *drawable, const struct wgl_pixel_format *desc, GLuint fbo ) +{ + const struct opengl_funcs *funcs = &display_funcs; + GLuint name; + + funcs->p_glGetNamedFramebufferAttachmentParameteriv( fbo, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&name ); + funcs->p_glDeleteRenderbuffers( 1, &name ); + TRACE( "drawable %p/%u destroyed color buffer %#x/%u\n", drawable, fbo, GL_COLOR_ATTACHMENT0, name ); + + funcs->p_glDeleteFramebuffers( 1, &fbo ); + TRACE( "drawable %p destroyed framebuffer %u\n", drawable, fbo ); +} + +static void framebuffer_surface_destroy( struct opengl_drawable *drawable ) +{ + TRACE( "%s\n", debugstr_opengl_drawable( drawable ) ); +} + +static void framebuffer_surface_flush( struct opengl_drawable *drawable, UINT flags ) +{ + struct wgl_pixel_format desc = pixel_formats[drawable->format - 1]; + RECT rect; + + TRACE( "%s, flags %#x\n", debugstr_opengl_drawable( drawable ), flags ); + + NtUserGetClientRect( drawable->client->hwnd, &rect, NtUserGetDpiForWindow( drawable->client->hwnd ) ); + if (!rect.right) rect.right = 1; + if (!rect.bottom) rect.bottom = 1; + + if (flags & GL_FLUSH_WAS_CURRENT) + { + destroy_framebuffer( drawable, &desc, drawable->fbo ); + drawable->fbo = 0; + } + + if (flags & GL_FLUSH_SET_CURRENT) + { + drawable->fbo = create_framebuffer( drawable, &desc ); + if (!drawable->fbo) ERR( "Failed to create framebuffer object\n" ); + } + + if ((flags & (GL_FLUSH_UPDATED | GL_FLUSH_SET_CURRENT)) && drawable->fbo) + { + TRACE( "Resizing drawable %p/%u to %ux%u\n", drawable, drawable->fbo, rect.right, rect.bottom ); + resize_framebuffer( drawable, &desc, drawable->fbo, rect.right, rect.bottom ); + } +} + +static BOOL framebuffer_surface_swap( struct opengl_drawable *drawable ) +{ + TRACE( "%s\n", debugstr_opengl_drawable( drawable ) ); + return TRUE; +} + +static const struct opengl_drawable_funcs framebuffer_surface_funcs = +{ + .destroy = framebuffer_surface_destroy, + .flush = framebuffer_surface_flush, + .swap = framebuffer_surface_swap, +}; + +static struct opengl_drawable *framebuffer_surface_create( int format, struct client_surface *client ) +{ + struct framebuffer_surface *surface; + if (!(surface = opengl_drawable_create( sizeof(*surface), &framebuffer_surface_funcs, format, client ))) return NULL; + return &surface->base; +} + #ifdef SONAME_LIBEGL
-static const struct opengl_drawable_funcs egldrv_surface_funcs; static const struct opengl_drawable_funcs egldrv_pbuffer_funcs;
static inline EGLConfig egl_config_for_format( const struct egl_platform *egl, int format ) @@ -392,8 +540,9 @@ static BOOL egldrv_surface_create( HWND hwnd, HDC hdc, int format, struct opengl struct client_surface *client;
if (!(client = nulldrv_client_surface_create( hwnd ))) return FALSE; - *drawable = opengl_drawable_create( sizeof(**drawable), &egldrv_surface_funcs, format, client ); + *drawable = framebuffer_surface_create( format, client ); client_surface_release( client ); + return !!*drawable; }
@@ -569,29 +718,6 @@ static BOOL egldrv_make_current( struct opengl_drawable *draw, struct opengl_dra return funcs->p_eglMakeCurrent( egl->display, context ? draw->surface : EGL_NO_SURFACE, context ? read->surface : EGL_NO_SURFACE, context ); }
-static void egldrv_surface_destroy( struct opengl_drawable *drawable ) -{ - TRACE( "%s\n", debugstr_opengl_drawable( drawable ) ); -} - -static void egldrv_surface_flush( struct opengl_drawable *drawable, UINT flags ) -{ - TRACE( "%s flags %#x\n", debugstr_opengl_drawable( drawable ), flags ); -} - -static BOOL egldrv_surface_swap( struct opengl_drawable *drawable ) -{ - TRACE( "%s\n", debugstr_opengl_drawable( drawable ) ); - return TRUE; -} - -static const struct opengl_drawable_funcs egldrv_surface_funcs = -{ - .destroy = egldrv_surface_destroy, - .flush = egldrv_surface_flush, - .swap = egldrv_surface_swap, -}; - static void egldrv_pbuffer_destroy( struct opengl_drawable *drawable ) { TRACE( "%s\n", debugstr_opengl_drawable( drawable ) ); @@ -854,8 +980,6 @@ static const struct opengl_driver_funcs nulldrv_funcs = .p_make_current = nulldrv_make_current, };
-static const struct opengl_driver_funcs *driver_funcs = &nulldrv_funcs; - static const char *win32u_wglGetExtensionsStringARB( HDC hdc ) { TRACE( "hdc %p\n", hdc ); @@ -1840,6 +1964,16 @@ static void display_funcs_init(void) display_funcs.p_##func = default_funcs->p_##func; \ } ALL_GL_FUNCS + USE_GL_FUNC(glCheckNamedFramebufferStatus) + USE_GL_FUNC(glCreateFramebuffers) + USE_GL_FUNC(glCreateRenderbuffers) + USE_GL_FUNC(glDeleteFramebuffers) + USE_GL_FUNC(glDeleteRenderbuffers) + USE_GL_FUNC(glGetNamedFramebufferAttachmentParameteriv) + USE_GL_FUNC(glNamedFramebufferDrawBuffer) + USE_GL_FUNC(glNamedFramebufferReadBuffer) + USE_GL_FUNC(glNamedFramebufferRenderbuffer) + USE_GL_FUNC(glNamedRenderbufferStorageMultisample) #undef USE_GL_FUNC
display_funcs.p_wglGetProcAddress = win32u_wglGetProcAddress; diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 2b5395c96f9..5080e8c7fb1 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -157,6 +157,7 @@ struct opengl_drawable int format; /* pixel format of the drawable */ int interval; /* last set surface swap interval */ EGLSurface surface; /* surface for EGL based drivers */ + GLuint fbo; /* default FBO name when emulating framebuffer */ };
static inline const char *debugstr_opengl_drawable( struct opengl_drawable *drawable )
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 47 ++++++++++++++++++++++++++---------- include/wine/opengl_driver.h | 2 ++ 2 files changed, 36 insertions(+), 13 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 212faed4eb6..825be97d019 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -122,6 +122,8 @@ void *opengl_drawable_create( UINT size, const struct opengl_drawable_funcs *fun
drawable->format = format; drawable->interval = INT_MIN; + drawable->doublebuffer = !!(pixel_formats[format - 1].pfd.dwFlags & PFD_DOUBLEBUFFER); + drawable->stereo = !!(pixel_formats[format - 1].pfd.dwFlags & PFD_STEREO); if ((drawable->client = client)) client_surface_add_ref( client );
TRACE( "created %s\n", debugstr_opengl_drawable( drawable ) ); @@ -216,15 +218,22 @@ static GLenum color_format_from_pfd( const struct wgl_pixel_format *desc ) static GLuint create_framebuffer( struct opengl_drawable *drawable, const struct wgl_pixel_format *desc ) { const struct opengl_funcs *funcs = &display_funcs; - GLuint fbo, name; + GLuint count = 1, fbo, name; + + if (drawable->doublebuffer) count *= 2; + if (drawable->stereo) count *= 2;
funcs->p_glCreateFramebuffers( 1, &fbo ); - funcs->p_glCreateRenderbuffers( 1, &name ); - funcs->p_glNamedFramebufferRenderbuffer( fbo, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, name ); - TRACE( "drawable %p/%u created color buffer %#x/%u\n", drawable, fbo, GL_COLOR_ATTACHMENT0, name ); + + for (GLuint i = 0; i < count; i++) + { + funcs->p_glCreateRenderbuffers( 1, &name ); + funcs->p_glNamedFramebufferRenderbuffer( fbo, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER, name ); + TRACE( "drawable %p/%u created color buffer %#x/%u\n", drawable, fbo, GL_COLOR_ATTACHMENT0 + i, name ); + }
funcs->p_glNamedFramebufferDrawBuffer( fbo, GL_COLOR_ATTACHMENT0 ); - funcs->p_glNamedFramebufferReadBuffer( fbo, GL_COLOR_ATTACHMENT0 ); + funcs->p_glNamedFramebufferReadBuffer( fbo, drawable->doublebuffer ? GL_COLOR_ATTACHMENT1 : GL_COLOR_ATTACHMENT0 ); TRACE( "drawable %p created framebuffer %u\n", drawable, fbo );
return fbo; @@ -234,12 +243,18 @@ static void resize_framebuffer( struct opengl_drawable *drawable, const struct w int width, int height ) { const struct opengl_funcs *funcs = &display_funcs; - GLuint name; + GLuint count = 1, name; GLenum ret;
- funcs->p_glGetNamedFramebufferAttachmentParameteriv( fbo, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&name ); - funcs->p_glNamedRenderbufferStorageMultisample( name, desc->samples, color_format_from_pfd( desc ), width, height ); - TRACE( "drawable %p/%u resized color buffer %#x/%u to %d,%d\n", drawable, fbo, GL_COLOR_ATTACHMENT0, name, width, height ); + if (drawable->doublebuffer) count *= 2; + if (drawable->stereo) count *= 2; + + for (GLuint i = 0; i < count; i++) + { + funcs->p_glGetNamedFramebufferAttachmentParameteriv( fbo, GL_COLOR_ATTACHMENT0 + i, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&name ); + funcs->p_glNamedRenderbufferStorageMultisample( name, desc->samples, color_format_from_pfd( desc ), width, height ); + TRACE( "drawable %p/%u resized color buffer %#x/%u to %d,%d\n", drawable, fbo, GL_COLOR_ATTACHMENT0 + i, name, width, height ); + }
ret = funcs->p_glCheckNamedFramebufferStatus( fbo, GL_FRAMEBUFFER ); if (ret != GL_FRAMEBUFFER_COMPLETE) WARN( "glCheckNamedFramebufferStatus returned %#x\n", ret ); @@ -249,11 +264,17 @@ static void resize_framebuffer( struct opengl_drawable *drawable, const struct w static void destroy_framebuffer( struct opengl_drawable *drawable, const struct wgl_pixel_format *desc, GLuint fbo ) { const struct opengl_funcs *funcs = &display_funcs; - GLuint name; + GLuint count = 1, name; + + if (drawable->doublebuffer) count *= 2; + if (drawable->stereo) count *= 2;
- funcs->p_glGetNamedFramebufferAttachmentParameteriv( fbo, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&name ); - funcs->p_glDeleteRenderbuffers( 1, &name ); - TRACE( "drawable %p/%u destroyed color buffer %#x/%u\n", drawable, fbo, GL_COLOR_ATTACHMENT0, name ); + for (GLuint i = 0; i < count; i++) + { + funcs->p_glGetNamedFramebufferAttachmentParameteriv( fbo, GL_COLOR_ATTACHMENT0 + i, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&name ); + funcs->p_glDeleteRenderbuffers( 1, &name ); + TRACE( "drawable %p/%u destroyed color buffer %#x/%u\n", drawable, fbo, GL_COLOR_ATTACHMENT0 + i, name ); + }
funcs->p_glDeleteFramebuffers( 1, &fbo ); TRACE( "drawable %p destroyed framebuffer %u\n", drawable, fbo ); diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 5080e8c7fb1..386f8969b1b 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -156,6 +156,8 @@ struct opengl_drawable struct client_surface *client; /* underlying client surface */ int format; /* pixel format of the drawable */ int interval; /* last set surface swap interval */ + BOOL doublebuffer; /* pixel format is double buffered */ + BOOL stereo; /* pixel format is stereo buffered */ EGLSurface surface; /* surface for EGL based drivers */ GLuint fbo; /* default FBO name when emulating framebuffer */ };
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 825be97d019..9bb4a24339b 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -215,6 +215,26 @@ static GLenum color_format_from_pfd( const struct wgl_pixel_format *desc ) return 0; }
+static GLenum depth_format_from_pfd( const struct wgl_pixel_format *desc ) +{ + TRACE( "format bits %u/%u\n", desc->pfd.cStencilBits, desc->pfd.cDepthBits ); + + if (desc->pfd.cStencilBits) + { + if (desc->pfd.cDepthBits == 32) return GL_DEPTH32F_STENCIL8; + if (desc->pfd.cDepthBits == 24) return GL_DEPTH24_STENCIL8; + } + else + { + if (desc->pfd.cDepthBits == 32) return GL_DEPTH_COMPONENT32; + if (desc->pfd.cDepthBits == 24) return GL_DEPTH_COMPONENT24; + if (desc->pfd.cDepthBits == 16) return GL_DEPTH_COMPONENT16; + } + + FIXME( "Unsupported format bits %u/%u\n", desc->pfd.cStencilBits, desc->pfd.cDepthBits ); + return 0; +} + static GLuint create_framebuffer( struct opengl_drawable *drawable, const struct wgl_pixel_format *desc ) { const struct opengl_funcs *funcs = &display_funcs; @@ -232,6 +252,14 @@ static GLuint create_framebuffer( struct opengl_drawable *drawable, const struct TRACE( "drawable %p/%u created color buffer %#x/%u\n", drawable, fbo, GL_COLOR_ATTACHMENT0 + i, name ); }
+ if (desc->pfd.cDepthBits) + { + funcs->p_glCreateRenderbuffers( 1, &name ); + funcs->p_glNamedFramebufferRenderbuffer( fbo, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, name ); + if (desc->pfd.cStencilBits) funcs->p_glNamedFramebufferRenderbuffer( fbo, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, name ); + TRACE( "drawable %p/%u created depth buffer %u\n", drawable, fbo, name ); + } + funcs->p_glNamedFramebufferDrawBuffer( fbo, GL_COLOR_ATTACHMENT0 ); funcs->p_glNamedFramebufferReadBuffer( fbo, drawable->doublebuffer ? GL_COLOR_ATTACHMENT1 : GL_COLOR_ATTACHMENT0 ); TRACE( "drawable %p created framebuffer %u\n", drawable, fbo ); @@ -256,6 +284,13 @@ static void resize_framebuffer( struct opengl_drawable *drawable, const struct w TRACE( "drawable %p/%u resized color buffer %#x/%u to %d,%d\n", drawable, fbo, GL_COLOR_ATTACHMENT0 + i, name, width, height ); }
+ if (desc->pfd.cDepthBits) + { + funcs->p_glGetNamedFramebufferAttachmentParameteriv( fbo, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&name ); + funcs->p_glNamedRenderbufferStorageMultisample( name, desc->samples, depth_format_from_pfd( desc ), width, height ); + TRACE( "drawable %p/%u resized depth buffer %u to %d,%d\n", drawable, fbo, name, width, height ); + } + ret = funcs->p_glCheckNamedFramebufferStatus( fbo, GL_FRAMEBUFFER ); if (ret != GL_FRAMEBUFFER_COMPLETE) WARN( "glCheckNamedFramebufferStatus returned %#x\n", ret ); TRACE( "drawable %p/%u resized buffers to %d,%d\n", drawable, fbo, width, height ); @@ -276,6 +311,13 @@ static void destroy_framebuffer( struct opengl_drawable *drawable, const struct TRACE( "drawable %p/%u destroyed color buffer %#x/%u\n", drawable, fbo, GL_COLOR_ATTACHMENT0 + i, name ); }
+ if (desc->pfd.cDepthBits) + { + funcs->p_glGetNamedFramebufferAttachmentParameteriv( fbo, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&name ); + funcs->p_glDeleteRenderbuffers( 1, &name ); + TRACE( "drawable %p/%u destroyed depth buffer %u\n", drawable, fbo, name ); + } + funcs->p_glDeleteFramebuffers( 1, &fbo ); TRACE( "drawable %p destroyed framebuffer %u\n", drawable, fbo ); }
This merge request was approved by Huw Davies.