From: Rémi Bernon rbernon@codeweavers.com
Based on a patch from Derek Lesho. --- dlls/opengl32/make_opengl | 2 ++ dlls/opengl32/unix_thunks.c | 12 +++----- dlls/opengl32/unix_thunks.h | 2 ++ dlls/opengl32/unix_wgl.c | 36 +++++++++++++++++++++++ dlls/win32u/opengl.c | 56 ++++++++++++++++++++++++++++++++++-- dlls/win32u/tests/d3dkmt.c | 24 +++++++--------- include/wine/opengl_driver.h | 1 + 7 files changed, 108 insertions(+), 25 deletions(-)
diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index c8f6a5a7a49..3c862943b64 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -205,6 +205,8 @@ my %manual_unix_thunks = "glGetFramebufferParameterivEXT" => 1, "glGetInteger64v" => 1, "glGetIntegerv" => 1, + "glGetUnsignedBytevEXT" => 1, + "glGetUnsignedBytei_vEXT" => 1, "glGetString" => 1, "glGetStringi" => 1, "glNamedFramebufferDrawBuffer" => 1, diff --git a/dlls/opengl32/unix_thunks.c b/dlls/opengl32/unix_thunks.c index 47b3c84623c..58cbb561160 100644 --- a/dlls/opengl32/unix_thunks.c +++ b/dlls/opengl32/unix_thunks.c @@ -11529,16 +11529,14 @@ static NTSTATUS ext_glGetUniformuivEXT( void *args ) static NTSTATUS ext_glGetUnsignedBytei_vEXT( void *args ) { struct glGetUnsignedBytei_vEXT_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - funcs->p_glGetUnsignedBytei_vEXT( params->target, params->index, params->data ); + wrap_glGetUnsignedBytei_vEXT( params->teb, params->target, params->index, params->data ); return STATUS_SUCCESS; }
static NTSTATUS ext_glGetUnsignedBytevEXT( void *args ) { struct glGetUnsignedBytevEXT_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - funcs->p_glGetUnsignedBytevEXT( params->pname, params->data ); + wrap_glGetUnsignedBytevEXT( params->teb, params->pname, params->data ); return STATUS_SUCCESS; }
@@ -51620,8 +51618,7 @@ static NTSTATUS wow64_ext_glGetUnsignedBytei_vEXT( void *args ) PTR32 data; } *params = args; TEB *teb = get_teb64( params->teb ); - const struct opengl_funcs *funcs = teb->glTable; - funcs->p_glGetUnsignedBytei_vEXT( params->target, params->index, ULongToPtr(params->data) ); + wrap_glGetUnsignedBytei_vEXT( teb, params->target, params->index, ULongToPtr(params->data) ); return STATUS_SUCCESS; }
@@ -51634,8 +51631,7 @@ static NTSTATUS wow64_ext_glGetUnsignedBytevEXT( void *args ) PTR32 data; } *params = args; TEB *teb = get_teb64( params->teb ); - const struct opengl_funcs *funcs = teb->glTable; - funcs->p_glGetUnsignedBytevEXT( params->pname, ULongToPtr(params->data) ); + wrap_glGetUnsignedBytevEXT( teb, params->pname, ULongToPtr(params->data) ); return STATUS_SUCCESS; }
diff --git a/dlls/opengl32/unix_thunks.h b/dlls/opengl32/unix_thunks.h index 3f00ad63832..70260b735fd 100644 --- a/dlls/opengl32/unix_thunks.h +++ b/dlls/opengl32/unix_thunks.h @@ -33,6 +33,8 @@ extern void wrap_glFramebufferReadBufferEXT( TEB *teb, GLuint framebuffer, GLenu extern void wrap_glGetFramebufferParameterivEXT( TEB *teb, GLuint framebuffer, GLenum pname, GLint *params ); extern void wrap_glGetInteger64v( TEB *teb, GLenum pname, GLint64 *data ); extern const GLubyte *wrap_glGetStringi( TEB *teb, GLenum name, GLuint index ); +extern void wrap_glGetUnsignedBytei_vEXT( TEB *teb, GLenum target, GLuint index, GLubyte *data ); +extern void wrap_glGetUnsignedBytevEXT( TEB *teb, GLenum pname, GLubyte *data ); extern void wrap_glNamedFramebufferDrawBuffer( TEB *teb, GLuint framebuffer, GLenum buf ); extern void wrap_glNamedFramebufferDrawBuffers( TEB *teb, GLuint framebuffer, GLsizei n, const GLenum *bufs ); extern void wrap_glNamedFramebufferReadBuffer( TEB *teb, GLuint framebuffer, GLenum src ); diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 48884fef88f..0e07565cea4 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -861,6 +861,7 @@ static BOOL get_default_fbo_integer( struct context *ctx, struct opengl_drawable
static BOOL get_integer( TEB *teb, GLenum pname, GLint *data ) { + const struct opengl_funcs *funcs = teb->glTable; struct opengl_drawable *draw, *read; struct context *ctx;
@@ -889,11 +890,46 @@ static BOOL get_integer( TEB *teb, GLenum pname, GLint *data ) if (!read->read_fbo) break; *data = ctx->read_fbo; return TRUE; + case GL_NUM_DEVICE_UUIDS_EXT: + case GL_DEVICE_NODE_MASK_EXT: + if (!funcs->p_query_renderer) break; + return funcs->p_query_renderer( 0, pname, data ); }
return get_default_fbo_integer( ctx, draw, read, pname, data ); }
+void wrap_glGetUnsignedBytei_vEXT( TEB *teb, GLenum target, GLuint index, GLubyte *data ) +{ + const struct opengl_funcs *funcs = teb->glTable; + + switch (target) + { + case GL_DEVICE_UUID_EXT: + if (!funcs->p_query_renderer) break; + funcs->p_query_renderer( index, target, data ); + return; + } + + return funcs->p_glGetUnsignedBytei_vEXT( target, index, data ); +} + +void wrap_glGetUnsignedBytevEXT( TEB *teb, GLenum pname, GLubyte *data ) +{ + const struct opengl_funcs *funcs = teb->glTable; + + switch (pname) + { + case GL_DRIVER_UUID_EXT: + case GL_DEVICE_LUID_EXT: + if (!funcs->p_query_renderer) break; + funcs->p_query_renderer( 0, pname, data ); + return; + } + + return funcs->p_glGetUnsignedBytevEXT( pname, data ); +} + const GLubyte *wrap_glGetString( TEB *teb, GLenum name ) { const struct opengl_funcs *funcs = teb->glTable; diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index cda47d8cfaf..691b1c0820e 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -1073,6 +1073,7 @@ static void init_device_info( struct egl_platform *egl, const struct opengl_func { static const UINT versions[] = {46, 45, 44, 43, 42, 41, 40, 33, 32, 31, 30, 21, 20, 15, 14, 13, 12, 11, 10, 0}; EGLContext core_context = EGL_NO_CONTEXT, compat_context = EGL_NO_CONTEXT, context = EGL_NO_CONTEXT; + BOOL has_device_persistent_id; int i, count, values[3] = {0}; const char *extensions, *str; EGLConfig config; @@ -1095,13 +1096,11 @@ static void init_device_info( struct egl_platform *egl, const struct opengl_func TRACE( " - device_id: %#x\n", egl->device_id ); TRACE( " - vendor_id: %#x\n", egl->vendor_id );
- if (has_extension( extensions, "EGL_EXT_device_persistent_id" )) + if ((has_device_persistent_id = has_extension( extensions, "EGL_EXT_device_persistent_id" ))) { funcs->p_eglQueryDeviceBinaryEXT( egl->device, EGL_DEVICE_UUID_EXT, sizeof(egl->device_uuid), &egl->device_uuid, &count ); funcs->p_eglQueryDeviceBinaryEXT( egl->device, EGL_DRIVER_UUID_EXT, sizeof(egl->driver_uuid), &egl->driver_uuid, &count ); } - TRACE( " - device_uuid: %s\n", debugstr_guid(&egl->device_uuid) ); - TRACE( " - driver_uuid: %s\n", debugstr_guid(&egl->driver_uuid) );
funcs->p_eglBindAPI( EGL_OPENGL_API ); funcs->p_eglGetConfigs( egl->display, &config, 1, &count ); @@ -1165,9 +1164,18 @@ static void init_device_info( struct egl_platform *egl, const struct opengl_func } TRACE( " - video_memory: %u MiB\n", egl->video_memory );
+ if (!has_device_persistent_id && (has_extension( extensions, "GL_EXT_memory_object" ) || has_extension( extensions, "GL_EXT_semaphore" ))) + { + funcs->p_glGetUnsignedBytevEXT( GL_DRIVER_UUID_EXT, (GLubyte *)&egl->driver_uuid ); + funcs->p_glGetUnsignedBytei_vEXT( GL_DEVICE_UUID_EXT, 0, (GLubyte *)&egl->device_uuid ); + } + funcs->p_eglMakeCurrent( egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT ); }
+ TRACE( " - device_uuid: %s\n", debugstr_guid(&egl->device_uuid) ); + TRACE( " - driver_uuid: %s\n", debugstr_guid(&egl->driver_uuid) ); + if (compat_context) funcs->p_eglDestroyContext( egl->display, compat_context ); if (core_context) funcs->p_eglDestroyContext( egl->display, core_context );
@@ -2380,6 +2388,45 @@ static struct egl_platform *egl_platform_from_index( GLint index ) return NULL; }
+static BOOL win32u_query_renderer( UINT index, UINT attribute, void *value ) +{ + struct egl_platform *egl; + LUID luid; + UINT mask; + + TRACE( "index %u, attribute %#x, value %p\n", index, attribute, value ); + + if (attribute == GL_NUM_DEVICE_UUIDS_EXT) + { + *(GLuint *)value = list_count( &devices_egl ); + return TRUE; + } + + if (!(egl = egl_platform_from_index( index ))) + { + set_gl_error( GL_INVALID_INDEX ); + return FALSE; + } + + switch (attribute) + { + case GL_DRIVER_UUID_EXT: + memcpy( value, &egl->driver_uuid, sizeof(egl->driver_uuid) ); + return TRUE; + case GL_DEVICE_UUID_EXT: + memcpy( value, &egl->device_uuid, sizeof(egl->device_uuid) ); + return TRUE; + case GL_DEVICE_LUID_EXT: + return get_gpu_luid_from_uuid( &egl->device_uuid, (LUID *)value, &mask ); + case GL_DEVICE_NODE_MASK_EXT: + return get_gpu_luid_from_uuid( &egl->device_uuid, &luid, value ); + default: + FIXME( "Unsupported attribute %#x\n", attribute ); + set_gl_error( GL_INVALID_ENUM ); + return FALSE; + } +} + static BOOL query_renderer_integer( struct egl_platform *egl, GLenum attribute, GLuint *value ) { switch (attribute) @@ -2503,6 +2550,8 @@ static void display_funcs_init(void) USE_GL_FUNC(glDeleteFramebuffers) USE_GL_FUNC(glDeleteRenderbuffers) USE_GL_FUNC(glGetNamedFramebufferAttachmentParameteriv) + USE_GL_FUNC(glGetUnsignedBytei_vEXT) + USE_GL_FUNC(glGetUnsignedBytevEXT) USE_GL_FUNC(glNamedFramebufferDrawBuffer) USE_GL_FUNC(glNamedFramebufferReadBuffer) USE_GL_FUNC(glNamedFramebufferRenderbuffer) @@ -2578,6 +2627,7 @@ static void display_funcs_init(void) if (!list_empty( &devices_egl )) { register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_WINE_query_renderer" ); + display_funcs.p_query_renderer = win32u_query_renderer; display_funcs.p_wglQueryCurrentRendererIntegerWINE = win32u_wglQueryCurrentRendererIntegerWINE; display_funcs.p_wglQueryCurrentRendererStringWINE = win32u_wglQueryCurrentRendererStringWINE; display_funcs.p_wglQueryRendererIntegerWINE = win32u_wglQueryRendererIntegerWINE; diff --git a/dlls/win32u/tests/d3dkmt.c b/dlls/win32u/tests/d3dkmt.c index f5f6573d0f0..87c117e142d 100644 --- a/dlls/win32u/tests/d3dkmt.c +++ b/dlls/win32u/tests/d3dkmt.c @@ -4216,6 +4216,8 @@ static struct opengl_device *create_opengl_device( HWND hwnd, LUID *luid )
const char *extensions, *ptr; struct opengl_device *dev; + unsigned int nodes = 0; + LUID device_luid = {0}; int format, count; GUID guid; BOOL ret; @@ -4274,22 +4276,16 @@ static struct opengl_device *create_opengl_device( HWND hwnd, LUID *luid ) ok_x4( glGetError(), ==, 0 ); ok( !IsEqualGUID( &GUID_NULL, &guid ), "got GL_DRIVER_UUID_EXT %s\n", debugstr_guid( &guid ) );
- if (!winetest_platform_is_wine) /* crashes in host drivers */ - { - LUID device_luid = {0}; - unsigned int nodes = 0; - - p_glGetUnsignedBytevEXT( GL_DEVICE_LUID_EXT, (GLubyte *)&device_luid ); - if (!dev->broken) ok_x4( glGetError(), ==, 0 ); - else ok_x4( glGetError(), ==, GL_INVALID_ENUM ); + p_glGetUnsignedBytevEXT( GL_DEVICE_LUID_EXT, (GLubyte *)&device_luid ); + if (!dev->broken) ok_x4( glGetError(), ==, 0 ); + else ok_x4( glGetError(), ==, GL_INVALID_ENUM );
- glGetIntegerv( GL_DEVICE_NODE_MASK_EXT, (GLint *)&nodes ); - if (!dev->broken) ok_x4( glGetError(), ==, 0 ); - else ok_x4( glGetError(), ==, GL_INVALID_ENUM ); - if (!dev->broken) ok_u4( nodes, !=, 0 ); + glGetIntegerv( GL_DEVICE_NODE_MASK_EXT, (GLint *)&nodes ); + if (!dev->broken) ok_x4( glGetError(), ==, 0 ); + else ok_x4( glGetError(), ==, GL_INVALID_ENUM ); + if (!dev->broken) ok_u4( nodes, !=, 0 );
- if (luid_equals( luid, &luid_zero )) *luid = device_luid; - } + if (luid_equals( luid, &luid_zero )) *luid = device_luid;
return dev; } diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 2e4ee296159..cfdd4909b53 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -83,6 +83,7 @@ struct wgl_context /* interface between opengl32 and win32u */ struct opengl_funcs { + BOOL (*p_query_renderer)( UINT index, UINT attribute, void *value ); BOOL (*p_wgl_context_reset)( struct wgl_context *context, HDC hdc, struct wgl_context *share, const int *attribs ); BOOL (*p_wgl_context_flush)( struct wgl_context *context, void (*flush)(void), BOOL force_swap ); BOOL (*p_wglCopyContext)( struct wgl_context * hglrcSrc, struct wgl_context * hglrcDst, UINT mask );