1 /* Window-specific OpenGL functions implementation.
3 * Copyright (c) 1999 Lionel Ulmer
4 * Copyright (c) 2005 Raphael Junqueira
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
33 #define WIN32_NO_STATUS
40 #include "unix_private.h"
42 #include "wine/debug.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(opengl
);
46 static const BOOL is_win64
= (sizeof(void *) > sizeof(int));
48 static BOOL
is_wow64(void)
50 return !!NtCurrentTeb()->WowTebOffset
;
53 static pthread_mutex_t wgl_lock
= PTHREAD_MUTEX_INITIALIZER
;
55 /* handle management */
59 HANDLE_PBUFFER
= 0 << 12,
60 HANDLE_CONTEXT
= 1 << 12,
61 HANDLE_CONTEXT_V3
= 3 << 12,
62 HANDLE_GLSYNC
= 4 << 12,
63 HANDLE_TYPE_MASK
= 15 << 12,
68 DWORD tid
; /* thread that the context is current in */
69 void (CALLBACK
*debug_callback
)( GLenum
, GLenum
, GLuint
, GLenum
, GLsizei
, const GLchar
*, const void * ); /* debug callback */
70 const void *debug_user
; /* debug user parameter */
71 GLubyte
*extensions
; /* extension string */
72 GLuint
*disabled_exts
; /* indices of disabled extensions */
73 struct wgl_context
*drv_ctx
; /* driver context */
74 GLubyte
*version_string
;
80 const struct opengl_funcs
*funcs
;
83 struct opengl_context
*context
; /* for HANDLE_CONTEXT */
84 struct wgl_pbuffer
*pbuffer
; /* for HANDLE_PBUFFER */
85 struct wgl_handle
*next
; /* for free handles */
89 #define MAX_WGL_HANDLES 1024
90 static struct wgl_handle wgl_handles
[MAX_WGL_HANDLES
];
91 static struct wgl_handle
*next_free
;
92 static unsigned int handle_count
;
94 /* the current context is assumed valid and doesn't need locking */
95 static inline struct wgl_handle
*get_current_context_ptr( TEB
*teb
)
97 if (!teb
->glCurrentRC
) return NULL
;
98 return &wgl_handles
[LOWORD(teb
->glCurrentRC
) & ~HANDLE_TYPE_MASK
];
101 static inline HANDLE
next_handle( struct wgl_handle
*ptr
, enum wgl_handle_type type
)
103 WORD generation
= HIWORD( ptr
->handle
) + 1;
104 if (!generation
) generation
++;
105 ptr
->handle
= MAKELONG( ptr
- wgl_handles
, generation
) | type
;
106 return ULongToHandle( ptr
->handle
);
109 static struct wgl_handle
*get_handle_ptr( HANDLE handle
, enum wgl_handle_type type
)
111 unsigned int index
= LOWORD( handle
) & ~HANDLE_TYPE_MASK
;
113 if (index
< handle_count
&& ULongToHandle(wgl_handles
[index
].handle
) == handle
)
114 return &wgl_handles
[index
];
116 RtlSetLastWin32Error( ERROR_INVALID_HANDLE
);
120 static HANDLE
alloc_handle( enum wgl_handle_type type
, const struct opengl_funcs
*funcs
, void *user_ptr
)
123 struct wgl_handle
*ptr
= NULL
;
125 if ((ptr
= next_free
))
126 next_free
= next_free
->u
.next
;
127 else if (handle_count
< MAX_WGL_HANDLES
)
128 ptr
= &wgl_handles
[handle_count
++];
133 ptr
->u
.context
= user_ptr
;
134 handle
= next_handle( ptr
, type
);
136 else RtlSetLastWin32Error( ERROR_NOT_ENOUGH_MEMORY
);
140 static void free_handle_ptr( struct wgl_handle
*ptr
)
142 ptr
->handle
|= 0xffff;
143 ptr
->u
.next
= next_free
;
148 /* check if the extension is present in the list */
149 static BOOL
has_extension( const char *list
, const char *ext
, size_t len
)
153 while (*list
== ' ') list
++;
154 if (!strncmp( list
, ext
, len
) && (!list
[len
] || list
[len
] == ' ')) return TRUE
;
155 list
= strchr( list
, ' ' );
160 static GLubyte
*filter_extensions_list( const char *extensions
, const char *disabled
)
165 p
= str
= malloc( strlen( extensions
) + 2 );
166 if (!str
) return NULL
;
168 TRACE( "GL_EXTENSIONS:\n" );
172 while (*extensions
== ' ') extensions
++;
173 if (!*extensions
) break;
175 if (!(end
= strchr( extensions
, ' ' ))) end
= extensions
+ strlen( extensions
);
176 memcpy( p
, extensions
, end
- extensions
);
177 p
[end
- extensions
] = 0;
179 /* We do not support GL_MAP_PERSISTENT_BIT, and hence
180 * ARB_buffer_storage, on wow64. */
181 if (is_win64
&& is_wow64() && (!strcmp( p
, "GL_ARB_buffer_storage" ) || !strcmp( p
, "GL_EXT_buffer_storage" )))
183 TRACE( "-- %s (disabled due to wow64)\n", p
);
185 else if (!has_extension( disabled
, p
, strlen( p
) ))
187 TRACE( "++ %s\n", p
);
188 p
+= end
- extensions
;
193 TRACE( "-- %s (disabled by config)\n", p
);
198 return (GLubyte
*)str
;
201 static const char *parse_gl_version( const char *gl_version
, int *major
, int *minor
)
203 const char *ptr
= gl_version
;
205 *major
= atoi( ptr
);
207 ERR( "Invalid OpenGL major version %d.\n", *major
);
209 while (isdigit( *ptr
)) ++ptr
;
211 ERR( "Invalid OpenGL version string %s.\n", debugstr_a(gl_version
) );
213 *minor
= atoi( ptr
);
215 while (isdigit( *ptr
)) ++ptr
;
219 static GLuint
*filter_extensions_index( TEB
*teb
, const char *disabled
)
221 const struct opengl_funcs
*funcs
= teb
->glTable
;
222 const char *ext
, *version
;
223 GLuint
*disabled_index
;
224 GLint extensions_count
;
225 unsigned int i
= 0, j
;
228 if (!funcs
->ext
.p_glGetStringi
)
230 void **func_ptr
= (void **)&funcs
->ext
.p_glGetStringi
;
231 *func_ptr
= funcs
->wgl
.p_wglGetProcAddress( "glGetStringi" );
232 if (!funcs
->ext
.p_glGetStringi
) return NULL
;
235 version
= (const char *)funcs
->gl
.p_glGetString( GL_VERSION
);
236 parse_gl_version( version
, &major
, &minor
);
240 funcs
->gl
.p_glGetIntegerv( GL_NUM_EXTENSIONS
, &extensions_count
);
241 disabled_index
= malloc( extensions_count
* sizeof(*disabled_index
) );
242 if (!disabled_index
) return NULL
;
244 TRACE( "GL_EXTENSIONS:\n" );
246 for (j
= 0; j
< extensions_count
; ++j
)
248 ext
= (const char *)funcs
->ext
.p_glGetStringi( GL_EXTENSIONS
, j
);
250 /* We do not support GL_MAP_PERSISTENT_BIT, and hence
251 * ARB_buffer_storage, on wow64. */
252 if (is_win64
&& is_wow64() && (!strcmp( ext
, "GL_ARB_buffer_storage" ) || !strcmp( ext
, "GL_EXT_buffer_storage" )))
254 TRACE( "-- %s (disabled due to wow64)\n", ext
);
255 disabled_index
[i
++] = j
;
257 else if (!has_extension( disabled
, ext
, strlen( ext
) ))
259 TRACE( "++ %s\n", ext
);
263 TRACE( "-- %s (disabled by config)\n", ext
);
264 disabled_index
[i
++] = j
;
268 disabled_index
[i
] = ~0u;
269 return disabled_index
;
272 static inline void ascii_to_unicode( WCHAR
*dst
, const char *src
, size_t len
)
274 while (len
--) *dst
++ = (unsigned char)*src
++;
277 static inline UINT
asciiz_to_unicode( WCHAR
*dst
, const char *src
)
280 while ((*p
++ = *src
++));
281 return (p
- dst
) * sizeof(WCHAR
);
284 static inline void unicode_to_ascii( char *dst
, const WCHAR
*src
, size_t len
)
286 while (len
--) *dst
++ = *src
++;
289 static HKEY
reg_open_key( HKEY root
, const WCHAR
*name
, ULONG name_len
)
291 UNICODE_STRING nameW
= { name_len
, name_len
, (WCHAR
*)name
};
292 OBJECT_ATTRIBUTES attr
;
295 attr
.Length
= sizeof(attr
);
296 attr
.RootDirectory
= root
;
297 attr
.ObjectName
= &nameW
;
299 attr
.SecurityDescriptor
= NULL
;
300 attr
.SecurityQualityOfService
= NULL
;
302 return NtOpenKeyEx( &ret
, MAXIMUM_ALLOWED
, &attr
, 0 ) ? 0 : ret
;
305 static HKEY
open_hkcu_key( const char *name
)
313 DWORD_PTR sid_data
[(sizeof(TOKEN_USER
) + SECURITY_MAX_SID_SIZE
) / sizeof(DWORD_PTR
)];
314 DWORD i
, len
= sizeof(sid_data
);
317 if (NtQueryInformationToken( GetCurrentThreadEffectiveToken(), TokenUser
, sid_data
, len
, &len
))
320 sid
= ((TOKEN_USER
*)sid_data
)->User
.Sid
;
321 len
= sprintf( buffer
, "\\Registry\\User\\S-%u-%u", sid
->Revision
,
322 (int)MAKELONG( MAKEWORD( sid
->IdentifierAuthority
.Value
[5],
323 sid
->IdentifierAuthority
.Value
[4] ),
324 MAKEWORD( sid
->IdentifierAuthority
.Value
[3],
325 sid
->IdentifierAuthority
.Value
[2] )));
326 for (i
= 0; i
< sid
->SubAuthorityCount
; i
++)
327 len
+= sprintf( buffer
+ len
, "-%u", (int)sid
->SubAuthority
[i
] );
329 ascii_to_unicode( bufferW
, buffer
, len
);
330 hkcu
= reg_open_key( NULL
, bufferW
, len
* sizeof(WCHAR
) );
333 return reg_open_key( hkcu
, bufferW
, asciiz_to_unicode( bufferW
, name
) - sizeof(WCHAR
) );
336 static NTSTATUS
query_reg_value( HKEY hkey
, const WCHAR
*name
, KEY_VALUE_PARTIAL_INFORMATION
*info
, ULONG size
)
338 unsigned int name_size
= name
? lstrlenW( name
) * sizeof(WCHAR
) : 0;
339 UNICODE_STRING nameW
= { name_size
, name_size
, (WCHAR
*)name
};
341 return NtQueryValueKey( hkey
, &nameW
, KeyValuePartialInformation
, info
, size
, &size
);
344 /* build the extension string by filtering out the disabled extensions */
345 static BOOL
filter_extensions( TEB
* teb
, const char *extensions
, GLubyte
**exts_list
, GLuint
**disabled_exts
)
347 static const char *disabled
;
354 /* @@ Wine registry key: HKCU\Software\Wine\OpenGL */
355 if ((hkey
= open_hkcu_key( "Software\\Wine\\OpenGL" )))
358 KEY_VALUE_PARTIAL_INFORMATION
*value
= (void *)buffer
;
359 static WCHAR disabled_extensionsW
[] = {'D','i','s','a','b','l','e','d','E','x','t','e','n','s','i','o','n','s',0};
361 if (!query_reg_value( hkey
, disabled_extensionsW
, value
, sizeof(buffer
) ))
363 ULONG len
= value
->DataLength
/ sizeof(WCHAR
);
365 unicode_to_ascii( buffer
, (WCHAR
*)value
->Data
, len
);
367 str
= strdup( buffer
);
373 if (InterlockedCompareExchangePointer( (void **)&disabled
, str
, NULL
)) free( str
);
378 if (extensions
&& !*exts_list
) *exts_list
= filter_extensions_list( extensions
, disabled
);
379 if (!*disabled_exts
) *disabled_exts
= filter_extensions_index( teb
, disabled
);
380 return (exts_list
&& *exts_list
) || *disabled_exts
;
383 static const GLuint
*disabled_extensions_index( TEB
*teb
)
385 struct wgl_handle
*ptr
= get_current_context_ptr( teb
);
386 GLuint
**disabled
= &ptr
->u
.context
->disabled_exts
;
387 if (*disabled
|| filter_extensions( teb
, NULL
, NULL
, disabled
)) return *disabled
;
391 /* Check if a GL extension is supported */
392 static BOOL
check_extension_support( TEB
*teb
, const char *extension
, const char *available_extensions
)
394 const struct opengl_funcs
*funcs
= teb
->glTable
;
397 TRACE( "Checking for extension '%s'\n", extension
);
399 /* We use the GetProcAddress function from the display driver to retrieve function pointers
400 * for OpenGL and WGL extensions. In case of winex11.drv the OpenGL extension lookup is done
401 * using glXGetProcAddress. This function is quite unreliable in the sense that its specs don't
402 * require the function to return NULL when an extension isn't found. For this reason we check
403 * if the OpenGL extension required for the function we are looking up is supported. */
405 while ((len
= strcspn( extension
, " " )))
407 /* Check if the extension is part of the GL extension string to see if it is supported. */
408 if (has_extension( available_extensions
, extension
, len
)) return TRUE
;
410 /* In general an OpenGL function starts as an ARB/EXT extension and at some stage
411 * it becomes part of the core OpenGL library and can be reached without the ARB/EXT
412 * suffix as well. In the extension table, these functions contain GL_VERSION_major_minor.
413 * Check if we are searching for a core GL function */
414 if (!strncmp( extension
, "GL_VERSION_", 11 ))
416 const GLubyte
*gl_version
= funcs
->gl
.p_glGetString( GL_VERSION
);
417 const char *version
= extension
+ 11; /* Move past 'GL_VERSION_' */
421 ERR( "No OpenGL version found!\n" );
425 /* Compare the major/minor version numbers of the native OpenGL library and what is required by the function.
426 * The gl_version string is guaranteed to have at least a major/minor and sometimes it has a release number as well. */
427 if ((gl_version
[0] > version
[0]) || ((gl_version
[0] == version
[0]) && (gl_version
[2] >= version
[2]))) return TRUE
;
429 WARN( "The function requires OpenGL version '%c.%c' while your drivers only provide '%c.%c'\n",
430 version
[0], version
[2], gl_version
[0], gl_version
[2] );
433 if (extension
[len
] == ' ') len
++;
440 static void wrap_glGetIntegerv( TEB
*teb
, GLenum pname
, GLint
*data
)
442 const struct opengl_funcs
*funcs
= teb
->glTable
;
443 const GLuint
*disabled
;
445 funcs
->gl
.p_glGetIntegerv( pname
, data
);
447 if (pname
== GL_NUM_EXTENSIONS
&& (disabled
= disabled_extensions_index( teb
)))
448 while (*disabled
++ != ~0u) (*data
)--;
450 if (is_win64
&& is_wow64())
452 /* 4.4 depends on ARB_buffer_storage, which we don't support on wow64. */
453 if (pname
== GL_MAJOR_VERSION
&& *data
> 4)
455 else if (pname
== GL_MINOR_VERSION
)
459 funcs
->gl
.p_glGetIntegerv( GL_MAJOR_VERSION
, &major
);
460 if (major
== 4 && *data
> 3)
466 static const GLubyte
*wrap_glGetString( TEB
*teb
, GLenum name
)
468 const struct opengl_funcs
*funcs
= teb
->glTable
;
471 if ((ret
= funcs
->gl
.p_glGetString( name
)))
473 if (name
== GL_EXTENSIONS
)
475 struct wgl_handle
*ptr
= get_current_context_ptr( teb
);
476 GLubyte
**extensions
= &ptr
->u
.context
->extensions
;
477 GLuint
**disabled
= &ptr
->u
.context
->disabled_exts
;
478 if (*extensions
|| filter_extensions( teb
, (const char *)ret
, extensions
, disabled
)) return *extensions
;
480 else if (name
== GL_VERSION
&& is_win64
&& is_wow64())
482 struct wgl_handle
*ptr
= get_current_context_ptr( teb
);
486 if (ptr
->u
.context
->version_string
)
487 return ptr
->u
.context
->version_string
;
489 rest
= parse_gl_version( (const char *)ret
, &major
, &minor
);
491 /* 4.4 depends on ARB_buffer_storage, which we don't support on wow64. */
492 if (major
> 4 || (major
== 4 && minor
>= 4))
494 char *str
= malloc( 3 + strlen( rest
) + 1 );
496 sprintf( str
, "4.3%s", rest
);
497 if (InterlockedCompareExchangePointer( (void **)&ptr
->u
.context
->version_string
, str
, NULL
))
499 return ptr
->u
.context
->version_string
;
507 static const GLubyte
*wrap_glGetStringi( TEB
*teb
, GLenum name
, GLuint index
)
509 const struct opengl_funcs
*funcs
= teb
->glTable
;
510 const GLuint
*disabled
;
512 if (!funcs
->ext
.p_glGetStringi
)
514 void **func_ptr
= (void **)&funcs
->ext
.p_glGetStringi
;
515 *func_ptr
= funcs
->wgl
.p_wglGetProcAddress( "glGetStringi" );
518 if (name
== GL_EXTENSIONS
&& (disabled
= disabled_extensions_index( teb
)))
519 while (index
>= *disabled
++) index
++;
521 return funcs
->ext
.p_glGetStringi( name
, index
);
524 static char *build_extension_list( TEB
*teb
)
526 GLint len
= 0, capacity
, i
, extensions_count
;
527 char *extension
, *tmp
, *available_extensions
;
529 wrap_glGetIntegerv( teb
, GL_NUM_EXTENSIONS
, &extensions_count
);
530 capacity
= 128 * extensions_count
;
532 if (!(available_extensions
= malloc( capacity
))) return NULL
;
533 for (i
= 0; i
< extensions_count
; ++i
)
535 extension
= (char *)wrap_glGetStringi( teb
, GL_EXTENSIONS
, i
);
536 capacity
= max( capacity
, len
+ strlen( extension
) + 2 );
537 if (!(tmp
= realloc( available_extensions
, capacity
))) break;
538 available_extensions
= tmp
;
539 len
+= sprintf( available_extensions
+ len
, "%s ", extension
);
541 if (len
) available_extensions
[len
- 1] = 0;
543 return available_extensions
;
546 static inline enum wgl_handle_type
get_current_context_type( TEB
*teb
)
548 if (!teb
->glCurrentRC
) return HANDLE_CONTEXT
;
549 return LOWORD(teb
->glCurrentRC
) & HANDLE_TYPE_MASK
;
552 /* Check if a GL extension is supported */
553 static BOOL
is_extension_supported( TEB
*teb
, const char *extension
)
555 enum wgl_handle_type type
= get_current_context_type( teb
);
556 char *available_extensions
= NULL
;
559 if (type
== HANDLE_CONTEXT
) available_extensions
= strdup( (const char *)wrap_glGetString( teb
, GL_EXTENSIONS
) );
560 if (!available_extensions
) available_extensions
= build_extension_list( teb
);
562 if (!available_extensions
) ERR( "No OpenGL extensions found, check if your OpenGL setup is correct!\n" );
563 else ret
= check_extension_support( teb
, extension
, available_extensions
);
565 free( available_extensions
);
569 static int registry_entry_cmp( const void *a
, const void *b
)
571 const struct registry_entry
*entry_a
= a
, *entry_b
= b
;
572 return strcmp( entry_a
->name
, entry_b
->name
);
575 static PROC
wrap_wglGetProcAddress( TEB
*teb
, LPCSTR name
)
577 const struct registry_entry entry
= {.name
= name
}, *found
;
578 struct opengl_funcs
*funcs
= teb
->glTable
;
579 const void **func_ptr
;
581 /* Without an active context opengl32 doesn't know to what
582 * driver it has to dispatch wglGetProcAddress.
584 if (!get_current_context_ptr( teb
))
586 WARN( "No active WGL context found\n" );
590 if (!(found
= bsearch( &entry
, extension_registry
, extension_registry_size
, sizeof(entry
), registry_entry_cmp
)))
592 WARN( "Function %s unknown\n", name
);
596 func_ptr
= (const void **)&funcs
->ext
+ (found
- extension_registry
);
599 void *driver_func
= funcs
->wgl
.p_wglGetProcAddress( name
);
601 if (!is_extension_supported( teb
, found
->extension
))
604 static const struct { const char *name
, *alt
; } alternatives
[] =
606 { "glCopyTexSubImage3DEXT", "glCopyTexSubImage3D" }, /* needed by RuneScape */
607 { "glVertexAttribDivisor", "glVertexAttribDivisorARB"}, /* needed by Caffeine */
610 for (i
= 0; i
< ARRAY_SIZE(alternatives
); i
++)
612 if (strcmp( name
, alternatives
[i
].name
)) continue;
613 WARN( "Extension %s required for %s not supported, trying %s\n", found
->extension
,
614 name
, alternatives
[i
].alt
);
615 return wrap_wglGetProcAddress( teb
, alternatives
[i
].alt
);
618 WARN( "Extension %s required for %s not supported\n", found
->extension
, name
);
622 if (driver_func
== NULL
)
624 WARN( "Function %s not supported by driver\n", name
);
628 *func_ptr
= driver_func
;
631 /* Return the index into the extension registry instead of a useless
632 * function pointer, PE side will returns its own function pointers.
634 return (void *)(UINT_PTR
)(found
- extension_registry
);
637 static BOOL
wrap_wglCopyContext( HGLRC hglrcSrc
, HGLRC hglrcDst
, UINT mask
)
639 struct wgl_handle
*src
, *dst
;
642 if (!(src
= get_handle_ptr( hglrcSrc
, HANDLE_CONTEXT
))) return FALSE
;
643 if ((dst
= get_handle_ptr( hglrcDst
, HANDLE_CONTEXT
)))
645 if (src
->funcs
!= dst
->funcs
) RtlSetLastWin32Error( ERROR_INVALID_HANDLE
);
646 else ret
= src
->funcs
->wgl
.p_wglCopyContext( src
->u
.context
->drv_ctx
, dst
->u
.context
->drv_ctx
, mask
);
651 static HGLRC
wrap_wglCreateContext( HDC hdc
)
654 struct wgl_context
*drv_ctx
;
655 struct opengl_context
*context
;
656 const struct opengl_funcs
*funcs
= get_dc_funcs( hdc
);
658 if (!funcs
) return 0;
659 if (!(drv_ctx
= funcs
->wgl
.p_wglCreateContext( hdc
))) return 0;
660 if ((context
= calloc( 1, sizeof(*context
) )))
662 context
->drv_ctx
= drv_ctx
;
663 if (!(ret
= alloc_handle( HANDLE_CONTEXT
, funcs
, context
))) free( context
);
665 if (!ret
) funcs
->wgl
.p_wglDeleteContext( drv_ctx
);
669 static BOOL
wrap_wglMakeCurrent( TEB
*teb
, HDC hdc
, HGLRC hglrc
)
672 DWORD tid
= HandleToULong(teb
->ClientId
.UniqueThread
);
673 struct wgl_handle
*ptr
, *prev
= get_current_context_ptr( teb
);
677 if (!(ptr
= get_handle_ptr( hglrc
, HANDLE_CONTEXT
))) return FALSE
;
678 if (!ptr
->u
.context
->tid
|| ptr
->u
.context
->tid
== tid
)
680 ret
= ptr
->funcs
->wgl
.p_wglMakeCurrent( hdc
, ptr
->u
.context
->drv_ctx
);
683 if (prev
) prev
->u
.context
->tid
= 0;
684 ptr
->u
.context
->tid
= tid
;
685 teb
->glReserved1
[0] = hdc
;
686 teb
->glReserved1
[1] = hdc
;
687 teb
->glCurrentRC
= hglrc
;
688 teb
->glTable
= (void *)ptr
->funcs
;
693 RtlSetLastWin32Error( ERROR_BUSY
);
699 if (!prev
->funcs
->wgl
.p_wglMakeCurrent( 0, NULL
)) return FALSE
;
700 prev
->u
.context
->tid
= 0;
701 teb
->glCurrentRC
= 0;
702 teb
->glTable
= &null_opengl_funcs
;
706 RtlSetLastWin32Error( ERROR_INVALID_HANDLE
);
712 static BOOL
wrap_wglDeleteContext( TEB
*teb
, HGLRC hglrc
)
714 struct wgl_handle
*ptr
;
715 DWORD tid
= HandleToULong(teb
->ClientId
.UniqueThread
);
717 if (!(ptr
= get_handle_ptr( hglrc
, HANDLE_CONTEXT
))) return FALSE
;
718 if (ptr
->u
.context
->tid
&& ptr
->u
.context
->tid
!= tid
)
720 RtlSetLastWin32Error( ERROR_BUSY
);
723 if (hglrc
== teb
->glCurrentRC
) wrap_wglMakeCurrent( teb
, 0, 0 );
724 ptr
->funcs
->wgl
.p_wglDeleteContext( ptr
->u
.context
->drv_ctx
);
725 free( ptr
->u
.context
->version_string
);
726 free( ptr
->u
.context
->disabled_exts
);
727 free( ptr
->u
.context
->extensions
);
728 free( ptr
->u
.context
);
729 free_handle_ptr( ptr
);
733 static BOOL
wrap_wglShareLists( HGLRC hglrcSrc
, HGLRC hglrcDst
)
736 struct wgl_handle
*src
, *dst
;
738 if (!(src
= get_handle_ptr( hglrcSrc
, HANDLE_CONTEXT
))) return FALSE
;
739 if ((dst
= get_handle_ptr( hglrcDst
, HANDLE_CONTEXT
)))
741 if (src
->funcs
!= dst
->funcs
) RtlSetLastWin32Error( ERROR_INVALID_HANDLE
);
742 else ret
= src
->funcs
->wgl
.p_wglShareLists( src
->u
.context
->drv_ctx
, dst
->u
.context
->drv_ctx
);
747 static BOOL
wrap_wglBindTexImageARB( HPBUFFERARB handle
, int buffer
)
749 struct wgl_handle
*ptr
;
750 if (!(ptr
= get_handle_ptr( handle
, HANDLE_PBUFFER
))) return FALSE
;
751 return ptr
->funcs
->ext
.p_wglBindTexImageARB( ptr
->u
.pbuffer
, buffer
);
754 static HGLRC
wrap_wglCreateContextAttribsARB( HDC hdc
, HGLRC share
, const int *attribs
)
757 struct wgl_context
*drv_ctx
;
758 struct wgl_handle
*share_ptr
= NULL
;
759 struct opengl_context
*context
;
760 const struct opengl_funcs
*funcs
= get_dc_funcs( hdc
);
764 RtlSetLastWin32Error( ERROR_DC_NOT_FOUND
);
767 if (!funcs
->ext
.p_wglCreateContextAttribsARB
) return 0;
768 if (share
&& !(share_ptr
= get_handle_ptr( share
, HANDLE_CONTEXT
)))
770 RtlSetLastWin32Error( ERROR_INVALID_OPERATION
);
773 if ((drv_ctx
= funcs
->ext
.p_wglCreateContextAttribsARB( hdc
, share_ptr
? share_ptr
->u
.context
->drv_ctx
: NULL
, attribs
)))
775 if ((context
= calloc( 1, sizeof(*context
) )))
777 enum wgl_handle_type type
= HANDLE_CONTEXT
;
783 if (attribs
[0] == WGL_CONTEXT_MAJOR_VERSION_ARB
)
785 if (attribs
[1] >= 3) type
= HANDLE_CONTEXT_V3
;
792 context
->drv_ctx
= drv_ctx
;
793 if (!(ret
= alloc_handle( type
, funcs
, context
))) free( context
);
795 if (!ret
) funcs
->wgl
.p_wglDeleteContext( drv_ctx
);
801 static HPBUFFERARB
wrap_wglCreatePbufferARB( HDC hdc
, int format
, int width
, int height
, const int *attribs
)
804 struct wgl_pbuffer
*pbuffer
;
805 const struct opengl_funcs
*funcs
= get_dc_funcs( hdc
);
807 if (!funcs
|| !funcs
->ext
.p_wglCreatePbufferARB
) return 0;
808 if (!(pbuffer
= funcs
->ext
.p_wglCreatePbufferARB( hdc
, format
, width
, height
, attribs
))) return 0;
809 ret
= alloc_handle( HANDLE_PBUFFER
, funcs
, pbuffer
);
810 if (!ret
) funcs
->ext
.p_wglDestroyPbufferARB( pbuffer
);
814 static BOOL
wrap_wglDestroyPbufferARB( HPBUFFERARB handle
)
816 struct wgl_handle
*ptr
;
818 if (!(ptr
= get_handle_ptr( handle
, HANDLE_PBUFFER
))) return FALSE
;
819 ptr
->funcs
->ext
.p_wglDestroyPbufferARB( ptr
->u
.pbuffer
);
820 free_handle_ptr( ptr
);
824 static HDC
wrap_wglGetPbufferDCARB( HPBUFFERARB handle
)
826 struct wgl_handle
*ptr
;
827 if (!(ptr
= get_handle_ptr( handle
, HANDLE_PBUFFER
))) return 0;
828 return ptr
->funcs
->ext
.p_wglGetPbufferDCARB( ptr
->u
.pbuffer
);
831 static BOOL
wrap_wglMakeContextCurrentARB( TEB
*teb
, HDC draw_hdc
, HDC read_hdc
, HGLRC hglrc
)
834 DWORD tid
= HandleToULong(teb
->ClientId
.UniqueThread
);
835 struct wgl_handle
*ptr
, *prev
= get_current_context_ptr( teb
);
839 if (!(ptr
= get_handle_ptr( hglrc
, HANDLE_CONTEXT
))) return FALSE
;
840 if (!ptr
->u
.context
->tid
|| ptr
->u
.context
->tid
== tid
)
842 ret
= (ptr
->funcs
->ext
.p_wglMakeContextCurrentARB
&&
843 ptr
->funcs
->ext
.p_wglMakeContextCurrentARB( draw_hdc
, read_hdc
, ptr
->u
.context
->drv_ctx
));
846 if (prev
) prev
->u
.context
->tid
= 0;
847 ptr
->u
.context
->tid
= tid
;
848 teb
->glReserved1
[0] = draw_hdc
;
849 teb
->glReserved1
[1] = read_hdc
;
850 teb
->glCurrentRC
= hglrc
;
851 teb
->glTable
= (void *)ptr
->funcs
;
856 RtlSetLastWin32Error( ERROR_BUSY
);
862 if (!prev
->funcs
->wgl
.p_wglMakeCurrent( 0, NULL
)) return FALSE
;
863 prev
->u
.context
->tid
= 0;
864 teb
->glCurrentRC
= 0;
865 teb
->glTable
= &null_opengl_funcs
;
870 static BOOL
wrap_wglQueryPbufferARB( HPBUFFERARB handle
, int attrib
, int *value
)
872 struct wgl_handle
*ptr
;
873 if (!(ptr
= get_handle_ptr( handle
, HANDLE_PBUFFER
))) return FALSE
;
874 return ptr
->funcs
->ext
.p_wglQueryPbufferARB( ptr
->u
.pbuffer
, attrib
, value
);
877 static int wrap_wglReleasePbufferDCARB( HPBUFFERARB handle
, HDC hdc
)
879 struct wgl_handle
*ptr
;
880 if (!(ptr
= get_handle_ptr( handle
, HANDLE_PBUFFER
))) return FALSE
;
881 return ptr
->funcs
->ext
.p_wglReleasePbufferDCARB( ptr
->u
.pbuffer
, hdc
);
884 static BOOL
wrap_wglReleaseTexImageARB( HPBUFFERARB handle
, int buffer
)
886 struct wgl_handle
*ptr
;
887 if (!(ptr
= get_handle_ptr( handle
, HANDLE_PBUFFER
))) return FALSE
;
888 return ptr
->funcs
->ext
.p_wglReleaseTexImageARB( ptr
->u
.pbuffer
, buffer
);
891 static BOOL
wrap_wglSetPbufferAttribARB( HPBUFFERARB handle
, const int *attribs
)
893 struct wgl_handle
*ptr
;
894 if (!(ptr
= get_handle_ptr( handle
, HANDLE_PBUFFER
))) return FALSE
;
895 return ptr
->funcs
->ext
.p_wglSetPbufferAttribARB( ptr
->u
.pbuffer
, attribs
);
898 static void gl_debug_message_callback( GLenum source
, GLenum type
, GLuint id
, GLenum severity
,
899 GLsizei length
, const GLchar
*message
, const void *userParam
)
901 struct wine_gl_debug_message_params params
=
906 .severity
= severity
,
912 struct wgl_handle
*ptr
= (struct wgl_handle
*)userParam
;
916 fprintf( stderr
, "msg:gl_debug_message_callback called from native thread, severity %#x, message \"%.*s\".\n",
917 severity
, length
, message
);
921 if (!(params
.user_callback
= ptr
->u
.context
->debug_callback
)) return;
922 params
.user_data
= ptr
->u
.context
->debug_user
;
924 KeUserModeCallback( NtUserCallOpenGLDebugMessageCallback
, ¶ms
, sizeof(params
),
925 &ret_ptr
, &ret_len
);
928 static void wrap_glDebugMessageCallback( TEB
*teb
, GLDEBUGPROC callback
, const void *userParam
)
930 struct wgl_handle
*ptr
= get_current_context_ptr( teb
);
931 const struct opengl_funcs
*funcs
= teb
->glTable
;
933 if (!funcs
->ext
.p_glDebugMessageCallback
) return;
935 ptr
->u
.context
->debug_callback
= callback
;
936 ptr
->u
.context
->debug_user
= userParam
;
937 funcs
->ext
.p_glDebugMessageCallback( gl_debug_message_callback
, ptr
);
940 static void wrap_glDebugMessageCallbackAMD( TEB
*teb
, GLDEBUGPROCAMD callback
, void *userParam
)
942 struct wgl_handle
*ptr
= get_current_context_ptr( teb
);
943 const struct opengl_funcs
*funcs
= teb
->glTable
;
945 if (!funcs
->ext
.p_glDebugMessageCallbackAMD
) return;
947 ptr
->u
.context
->debug_callback
= callback
;
948 ptr
->u
.context
->debug_user
= userParam
;
949 funcs
->ext
.p_glDebugMessageCallbackAMD( gl_debug_message_callback
, ptr
);
952 static void wrap_glDebugMessageCallbackARB( TEB
*teb
, GLDEBUGPROCARB callback
, const void *userParam
)
954 struct wgl_handle
*ptr
= get_current_context_ptr( teb
);
955 const struct opengl_funcs
*funcs
= teb
->glTable
;
957 if (!funcs
->ext
.p_glDebugMessageCallbackARB
) return;
959 ptr
->u
.context
->debug_callback
= callback
;
960 ptr
->u
.context
->debug_user
= userParam
;
961 funcs
->ext
.p_glDebugMessageCallbackARB( gl_debug_message_callback
, ptr
);
964 NTSTATUS
wgl_wglCopyContext( void *args
)
966 struct wglCopyContext_params
*params
= args
;
967 pthread_mutex_lock( &wgl_lock
);
968 params
->ret
= wrap_wglCopyContext( params
->hglrcSrc
, params
->hglrcDst
, params
->mask
);
969 pthread_mutex_unlock( &wgl_lock
);
970 return STATUS_SUCCESS
;
973 NTSTATUS
wgl_wglCreateContext( void *args
)
975 struct wglCreateContext_params
*params
= args
;
976 pthread_mutex_lock( &wgl_lock
);
977 params
->ret
= wrap_wglCreateContext( params
->hDc
);
978 pthread_mutex_unlock( &wgl_lock
);
979 return STATUS_SUCCESS
;
982 NTSTATUS
wgl_wglDeleteContext( void *args
)
984 struct wglDeleteContext_params
*params
= args
;
985 pthread_mutex_lock( &wgl_lock
);
986 params
->ret
= wrap_wglDeleteContext( params
->teb
, params
->oldContext
);
987 pthread_mutex_unlock( &wgl_lock
);
988 return STATUS_SUCCESS
;
991 NTSTATUS
wgl_wglGetProcAddress( void *args
)
993 struct wglGetProcAddress_params
*params
= args
;
994 params
->ret
= wrap_wglGetProcAddress( params
->teb
, params
->lpszProc
);
995 return STATUS_SUCCESS
;
998 NTSTATUS
wgl_wglMakeCurrent( void *args
)
1000 struct wglMakeCurrent_params
*params
= args
;
1001 if (params
->newContext
) pthread_mutex_lock( &wgl_lock
);
1002 params
->ret
= wrap_wglMakeCurrent( params
->teb
, params
->hDc
, params
->newContext
);
1003 if (params
->newContext
) pthread_mutex_unlock( &wgl_lock
);
1004 return STATUS_SUCCESS
;
1007 NTSTATUS
wgl_wglShareLists( void *args
)
1009 struct wglShareLists_params
*params
= args
;
1010 pthread_mutex_lock( &wgl_lock
);
1011 params
->ret
= wrap_wglShareLists( params
->hrcSrvShare
, params
->hrcSrvSource
);
1012 pthread_mutex_unlock( &wgl_lock
);
1013 return STATUS_SUCCESS
;
1016 NTSTATUS
gl_glGetIntegerv( void *args
)
1018 struct glGetIntegerv_params
*params
= args
;
1019 wrap_glGetIntegerv( params
->teb
, params
->pname
, params
->data
);
1020 return STATUS_SUCCESS
;
1023 NTSTATUS
gl_glGetString( void *args
)
1025 struct glGetString_params
*params
= args
;
1026 params
->ret
= wrap_glGetString( params
->teb
, params
->name
);
1027 return STATUS_SUCCESS
;
1030 NTSTATUS
ext_glDebugMessageCallback( void *args
)
1032 struct glDebugMessageCallback_params
*params
= args
;
1033 wrap_glDebugMessageCallback( params
->teb
, params
->callback
, params
->userParam
);
1034 return STATUS_SUCCESS
;
1037 NTSTATUS
ext_glDebugMessageCallbackAMD( void *args
)
1039 struct glDebugMessageCallbackAMD_params
*params
= args
;
1040 wrap_glDebugMessageCallbackAMD( params
->teb
, params
->callback
, params
->userParam
);
1041 return STATUS_SUCCESS
;
1044 NTSTATUS
ext_glDebugMessageCallbackARB( void *args
)
1046 struct glDebugMessageCallbackARB_params
*params
= args
;
1047 wrap_glDebugMessageCallbackARB( params
->teb
, params
->callback
, params
->userParam
);
1048 return STATUS_SUCCESS
;
1051 NTSTATUS
ext_glGetStringi( void *args
)
1053 struct glGetStringi_params
*params
= args
;
1054 params
->ret
= wrap_glGetStringi( params
->teb
, params
->name
, params
->index
);
1055 return STATUS_SUCCESS
;
1058 NTSTATUS
ext_wglBindTexImageARB( void *args
)
1060 struct wglBindTexImageARB_params
*params
= args
;
1061 pthread_mutex_lock( &wgl_lock
);
1062 params
->ret
= wrap_wglBindTexImageARB( params
->hPbuffer
, params
->iBuffer
);
1063 pthread_mutex_unlock( &wgl_lock
);
1064 return STATUS_SUCCESS
;
1067 NTSTATUS
ext_wglCreateContextAttribsARB( void *args
)
1069 struct wglCreateContextAttribsARB_params
*params
= args
;
1070 pthread_mutex_lock( &wgl_lock
);
1071 params
->ret
= wrap_wglCreateContextAttribsARB( params
->hDC
, params
->hShareContext
, params
->attribList
);
1072 pthread_mutex_unlock( &wgl_lock
);
1073 return STATUS_SUCCESS
;
1076 NTSTATUS
ext_wglCreatePbufferARB( void *args
)
1078 struct wglCreatePbufferARB_params
*params
= args
;
1079 pthread_mutex_lock( &wgl_lock
);
1080 params
->ret
= wrap_wglCreatePbufferARB( params
->hDC
, params
->iPixelFormat
, params
->iWidth
, params
->iHeight
, params
->piAttribList
);
1081 pthread_mutex_unlock( &wgl_lock
);
1082 return STATUS_SUCCESS
;
1085 NTSTATUS
ext_wglDestroyPbufferARB( void *args
)
1087 struct wglDestroyPbufferARB_params
*params
= args
;
1088 pthread_mutex_lock( &wgl_lock
);
1089 params
->ret
= wrap_wglDestroyPbufferARB( params
->hPbuffer
);
1090 pthread_mutex_unlock( &wgl_lock
);
1091 return STATUS_SUCCESS
;
1094 NTSTATUS
ext_wglGetPbufferDCARB( void *args
)
1096 struct wglGetPbufferDCARB_params
*params
= args
;
1097 pthread_mutex_lock( &wgl_lock
);
1098 params
->ret
= wrap_wglGetPbufferDCARB( params
->hPbuffer
);
1099 pthread_mutex_unlock( &wgl_lock
);
1100 return STATUS_SUCCESS
;
1103 NTSTATUS
ext_wglMakeContextCurrentARB( void *args
)
1105 struct wglMakeContextCurrentARB_params
*params
= args
;
1106 if (params
->hglrc
) pthread_mutex_lock( &wgl_lock
);
1107 params
->ret
= wrap_wglMakeContextCurrentARB( params
->teb
, params
->hDrawDC
, params
->hReadDC
, params
->hglrc
);
1108 if (params
->hglrc
) pthread_mutex_unlock( &wgl_lock
);
1109 return STATUS_SUCCESS
;
1112 NTSTATUS
ext_wglQueryPbufferARB( void *args
)
1114 struct wglQueryPbufferARB_params
*params
= args
;
1115 pthread_mutex_lock( &wgl_lock
);
1116 params
->ret
= wrap_wglQueryPbufferARB( params
->hPbuffer
, params
->iAttribute
, params
->piValue
);
1117 pthread_mutex_unlock( &wgl_lock
);
1118 return STATUS_SUCCESS
;
1121 NTSTATUS
ext_wglReleasePbufferDCARB( void *args
)
1123 struct wglReleasePbufferDCARB_params
*params
= args
;
1124 pthread_mutex_lock( &wgl_lock
);
1125 params
->ret
= wrap_wglReleasePbufferDCARB( params
->hPbuffer
, params
->hDC
);
1126 pthread_mutex_unlock( &wgl_lock
);
1127 return STATUS_SUCCESS
;
1130 NTSTATUS
ext_wglReleaseTexImageARB( void *args
)
1132 struct wglReleaseTexImageARB_params
*params
= args
;
1133 pthread_mutex_lock( &wgl_lock
);
1134 params
->ret
= wrap_wglReleaseTexImageARB( params
->hPbuffer
, params
->iBuffer
);
1135 pthread_mutex_unlock( &wgl_lock
);
1136 return STATUS_SUCCESS
;
1139 NTSTATUS
ext_wglSetPbufferAttribARB( void *args
)
1141 struct wglSetPbufferAttribARB_params
*params
= args
;
1142 pthread_mutex_lock( &wgl_lock
);
1143 params
->ret
= wrap_wglSetPbufferAttribARB( params
->hPbuffer
, params
->piAttribList
);
1144 pthread_mutex_unlock( &wgl_lock
);
1145 return STATUS_SUCCESS
;
1148 NTSTATUS
thread_attach( void *args
)
1151 teb
->glTable
= &null_opengl_funcs
;
1152 return STATUS_SUCCESS
;
1155 NTSTATUS
process_detach( void *args
)
1157 return STATUS_SUCCESS
;
1162 typedef ULONG PTR32
;
1164 extern NTSTATUS
ext_glClientWaitSync( void *args
);
1165 extern NTSTATUS
ext_glDeleteSync( void *args
);
1166 extern NTSTATUS
ext_glFenceSync( void *args
);
1167 extern NTSTATUS
ext_glGetBufferPointerv( void *args
);
1168 extern NTSTATUS
ext_glGetBufferPointervARB( void *args
);
1169 extern NTSTATUS
ext_glGetNamedBufferPointerv( void *args
);
1170 extern NTSTATUS
ext_glGetNamedBufferPointervEXT( void *args
);
1171 extern NTSTATUS
ext_glGetSynciv( void *args
);
1172 extern NTSTATUS
ext_glIsSync( void *args
);
1173 extern NTSTATUS
ext_glMapBuffer( void *args
);
1175 extern NTSTATUS
ext_glUnmapBuffer( void *args
);
1176 extern NTSTATUS
ext_glUnmapBufferARB( void *args
);
1177 extern NTSTATUS
ext_glUnmapNamedBuffer( void *args
);
1178 extern NTSTATUS
ext_glUnmapNamedBufferEXT( void *args
);
1180 extern NTSTATUS
ext_glMapBufferARB( void *args
);
1181 extern NTSTATUS
ext_glMapBufferRange( void *args
);
1182 extern NTSTATUS
ext_glMapNamedBuffer( void *args
);
1183 extern NTSTATUS
ext_glMapNamedBufferEXT( void *args
);
1184 extern NTSTATUS
ext_glMapNamedBufferRange( void *args
);
1185 extern NTSTATUS
ext_glMapNamedBufferRangeEXT( void *args
);
1186 extern NTSTATUS
ext_glPathGlyphIndexRangeNV( void *args
);
1187 extern NTSTATUS
ext_glWaitSync( void *args
);
1188 extern NTSTATUS
ext_wglGetExtensionsStringARB( void *args
);
1189 extern NTSTATUS
ext_wglGetExtensionsStringEXT( void *args
);
1190 extern NTSTATUS
ext_wglQueryCurrentRendererStringWINE( void *args
);
1191 extern NTSTATUS
ext_wglQueryRendererStringWINE( void *args
);
1193 struct wow64_string_entry
1198 static struct wow64_string_entry
*wow64_strings
;
1199 static SIZE_T wow64_strings_count
;
1201 static PTR32
find_wow64_string( const char *str
, PTR32 wow64_str
)
1206 pthread_mutex_lock( &wgl_lock
);
1208 for (i
= 0; i
< wow64_strings_count
; i
++) if (wow64_strings
[i
].str
== str
) break;
1209 if (i
== wow64_strings_count
&& (tmp
= realloc( wow64_strings
, (i
+ 1) * sizeof(*wow64_strings
) )))
1211 wow64_strings
= tmp
;
1212 wow64_strings
[i
].str
= str
;
1213 wow64_strings
[i
].wow64_str
= 0;
1214 wow64_strings_count
+= 1;
1217 if (i
== wow64_strings_count
) ERR( "Failed to allocate memory for wow64 strings\n" );
1218 else if (wow64_strings
[i
].wow64_str
) wow64_str
= wow64_strings
[i
].wow64_str
;
1221 strcpy( UlongToPtr(wow64_str
), (char *)str
);
1222 wow64_strings
[i
].wow64_str
= wow64_str
;
1225 pthread_mutex_unlock( &wgl_lock
);
1230 static inline void update_teb32_context( TEB
*teb
)
1234 if (!teb
->WowTebOffset
) return;
1235 teb32
= (char *)teb
+ teb
->WowTebOffset
;
1237 ((TEB32
*)teb32
)->glCurrentRC
= (UINT_PTR
)teb
->glCurrentRC
;
1238 ((TEB32
*)teb32
)->glReserved1
[0] = (UINT_PTR
)teb
->glReserved1
[0];
1239 ((TEB32
*)teb32
)->glReserved1
[1] = (UINT_PTR
)teb
->glReserved1
[1];
1242 NTSTATUS
wow64_wgl_wglCreateContext( void *args
)
1250 struct wglCreateContext_params params
=
1252 .teb
= get_teb64(params32
->teb
),
1253 .hDc
= ULongToPtr(params32
->hDc
),
1256 if ((status
= wgl_wglCreateContext( ¶ms
))) return status
;
1257 params32
->ret
= (UINT_PTR
)params
.ret
;
1258 return STATUS_SUCCESS
;
1261 NTSTATUS
wow64_ext_wglCreateContextAttribsARB( void *args
)
1267 PTR32 hShareContext
;
1271 struct wglCreateContextAttribsARB_params params
=
1273 .teb
= get_teb64(params32
->teb
),
1274 .hDC
= ULongToPtr(params32
->hDC
),
1275 .hShareContext
= ULongToPtr(params32
->hShareContext
),
1276 .attribList
= ULongToPtr(params32
->attribList
),
1279 if ((status
= ext_wglCreateContextAttribsARB( ¶ms
))) return status
;
1280 params32
->ret
= (UINT_PTR
)params
.ret
;
1281 return STATUS_SUCCESS
;
1284 NTSTATUS
wow64_ext_wglCreatePbufferARB( void *args
)
1296 struct wglCreatePbufferARB_params params
=
1298 .teb
= get_teb64(params32
->teb
),
1299 .hDC
= ULongToPtr(params32
->hDC
),
1300 .iPixelFormat
= params32
->iPixelFormat
,
1301 .iWidth
= params32
->iWidth
,
1302 .iHeight
= params32
->iHeight
,
1303 .piAttribList
= ULongToPtr(params32
->piAttribList
),
1306 if ((status
= ext_wglCreatePbufferARB( ¶ms
))) return status
;
1307 params32
->ret
= (UINT_PTR
)params
.ret
;
1308 return STATUS_SUCCESS
;
1311 NTSTATUS
wow64_wgl_wglDeleteContext( void *args
)
1319 struct wglDeleteContext_params params
=
1321 .teb
= get_teb64(params32
->teb
),
1322 .oldContext
= ULongToPtr(params32
->oldContext
),
1325 if (!(status
= wgl_wglDeleteContext( ¶ms
))) update_teb32_context( params
.teb
);
1326 params32
->ret
= params
.ret
;
1330 NTSTATUS
wow64_wgl_wglMakeCurrent( void *args
)
1339 struct wglMakeCurrent_params params
=
1341 .teb
= get_teb64(params32
->teb
),
1342 .hDc
= ULongToPtr(params32
->hDc
),
1343 .newContext
= ULongToPtr(params32
->newContext
),
1346 if (!(status
= wgl_wglMakeCurrent( ¶ms
))) update_teb32_context( params
.teb
);
1347 params32
->ret
= params
.ret
;
1351 NTSTATUS
wow64_ext_wglMakeContextCurrentARB( void *args
)
1361 struct wglMakeContextCurrentARB_params params
=
1363 .teb
= get_teb64(params32
->teb
),
1364 .hDrawDC
= ULongToPtr(params32
->hDrawDC
),
1365 .hReadDC
= ULongToPtr(params32
->hReadDC
),
1366 .hglrc
= ULongToPtr(params32
->hglrc
),
1369 if (!(status
= ext_wglMakeContextCurrentARB( ¶ms
))) update_teb32_context( params
.teb
);
1370 params32
->ret
= params
.ret
;
1374 NTSTATUS
wow64_ext_wglGetPbufferDCARB( void *args
)
1382 struct wglGetPbufferDCARB_params params
=
1384 .teb
= get_teb64(params32
->teb
),
1385 .hPbuffer
= (HPBUFFERARB
)ULongToPtr(params32
->hPbuffer
),
1388 if ((status
= ext_wglGetPbufferDCARB( ¶ms
))) return status
;
1389 params32
->ret
= (UINT_PTR
)params
.ret
;
1390 return STATUS_SUCCESS
;
1393 NTSTATUS
wow64_wgl_wglGetProcAddress( void *args
)
1401 struct wglGetProcAddress_params params
=
1403 .teb
= get_teb64(params32
->teb
),
1404 .lpszProc
= ULongToPtr(params32
->lpszProc
),
1407 if ((status
= wgl_wglGetProcAddress( ¶ms
))) return status
;
1408 params32
->ret
= (UINT_PTR
)params
.ret
;
1409 return STATUS_SUCCESS
;
1412 NTSTATUS
wow64_gl_glGetString( void *args
)
1420 struct glGetString_params params
=
1422 .teb
= get_teb64(params32
->teb
),
1423 .name
= params32
->name
,
1427 if ((status
= gl_glGetString( ¶ms
))) return status
;
1429 if (!(params32
->ret
= find_wow64_string( (char *)params
.ret
, params32
->ret
)))
1431 params32
->ret
= strlen( (char *)params
.ret
) + 1;
1432 return STATUS_BUFFER_TOO_SMALL
;
1435 return STATUS_SUCCESS
;
1438 NTSTATUS
wow64_ext_glGetStringi( void *args
)
1447 struct glGetStringi_params params
=
1449 .teb
= get_teb64(params32
->teb
),
1450 .name
= params32
->name
,
1451 .index
= params32
->index
,
1455 if ((status
= ext_glGetStringi( ¶ms
))) return status
;
1457 if (!(params32
->ret
= find_wow64_string( (char *)params
.ret
, params32
->ret
)))
1459 params32
->ret
= strlen( (char *)params
.ret
) + 1;
1460 return STATUS_BUFFER_TOO_SMALL
;
1463 return STATUS_SUCCESS
;
1466 NTSTATUS
wow64_ext_glPathGlyphIndexRangeNV( void *args
)
1473 GLbitfield fontStyle
;
1474 GLuint pathParameterTemplate
;
1476 GLuint baseAndCount
[2];
1479 struct glPathGlyphIndexRangeNV_params params
=
1481 .teb
= get_teb64(params32
->teb
),
1482 .fontTarget
= params32
->fontTarget
,
1483 .fontName
= ULongToPtr(params32
->fontName
),
1484 .fontStyle
= params32
->fontStyle
,
1485 .pathParameterTemplate
= params32
->pathParameterTemplate
,
1486 .emScale
= params32
->emScale
,
1487 .baseAndCount
= {params32
->baseAndCount
[0], params32
->baseAndCount
[1]},
1490 if ((status
= ext_glPathGlyphIndexRangeNV( ¶ms
))) return status
;
1491 params32
->ret
= params
.ret
;
1495 NTSTATUS
wow64_ext_wglGetExtensionsStringARB( void *args
)
1503 struct wglGetExtensionsStringARB_params params
=
1505 .teb
= get_teb64(params32
->teb
),
1506 .hdc
= ULongToPtr(params32
->hdc
),
1510 if ((status
= ext_wglGetExtensionsStringARB( ¶ms
))) return status
;
1512 if (!(params32
->ret
= find_wow64_string( params
.ret
, params32
->ret
)))
1514 params32
->ret
= strlen( params
.ret
) + 1;
1515 return STATUS_BUFFER_TOO_SMALL
;
1518 return STATUS_SUCCESS
;
1521 NTSTATUS
wow64_ext_wglGetExtensionsStringEXT( void *args
)
1528 struct wglGetExtensionsStringEXT_params params
=
1530 .teb
= get_teb64(params32
->teb
),
1534 if ((status
= ext_wglGetExtensionsStringEXT( ¶ms
))) return status
;
1536 if (!(params32
->ret
= find_wow64_string( params
.ret
, params32
->ret
)))
1538 params32
->ret
= strlen( params
.ret
) + 1;
1539 return STATUS_BUFFER_TOO_SMALL
;
1542 return STATUS_SUCCESS
;
1545 NTSTATUS
wow64_ext_wglQueryCurrentRendererStringWINE( void *args
)
1553 struct wglQueryCurrentRendererStringWINE_params params
=
1555 .teb
= get_teb64(params32
->teb
),
1556 .attribute
= params32
->attribute
,
1560 if ((status
= ext_wglQueryCurrentRendererStringWINE( ¶ms
))) return status
;
1562 if (!(params32
->ret
= find_wow64_string( params
.ret
, params32
->ret
)))
1564 params32
->ret
= strlen( params
.ret
) + 1;
1565 return STATUS_BUFFER_TOO_SMALL
;
1568 return STATUS_SUCCESS
;
1571 NTSTATUS
wow64_ext_wglQueryRendererStringWINE( void *args
)
1581 struct wglQueryRendererStringWINE_params params
=
1583 .teb
= get_teb64(params32
->teb
),
1584 .dc
= ULongToPtr(params32
->dc
),
1585 .renderer
= params32
->renderer
,
1586 .attribute
= params32
->attribute
,
1590 if ((status
= ext_wglQueryRendererStringWINE( ¶ms
))) return status
;
1592 if (!(params32
->ret
= find_wow64_string( params
.ret
, params32
->ret
)))
1594 params32
->ret
= strlen( params
.ret
) + 1;
1595 return STATUS_BUFFER_TOO_SMALL
;
1598 return STATUS_SUCCESS
;
1601 NTSTATUS
wow64_ext_glClientWaitSync( void *args
)
1603 struct wgl_handle
*handle
;
1614 pthread_mutex_lock( &wgl_lock
);
1616 if (!(handle
= get_handle_ptr( ULongToPtr(params32
->sync
), HANDLE_GLSYNC
)))
1617 status
= STATUS_INVALID_HANDLE
;
1620 struct glClientWaitSync_params params
=
1622 .teb
= get_teb64(params32
->teb
),
1623 .sync
= (GLsync
)handle
->u
.context
,
1624 .flags
= params32
->flags
,
1625 .timeout
= params32
->timeout
,
1627 status
= ext_glClientWaitSync( ¶ms
);
1628 params32
->ret
= params
.ret
;
1631 pthread_mutex_unlock( &wgl_lock
);
1635 NTSTATUS
wow64_ext_glDeleteSync( void *args
)
1637 struct wgl_handle
*handle
;
1645 pthread_mutex_lock( &wgl_lock
);
1647 if (!(handle
= get_handle_ptr( ULongToPtr(params32
->sync
), HANDLE_GLSYNC
)))
1648 status
= STATUS_INVALID_HANDLE
;
1651 struct glDeleteSync_params params
=
1653 .teb
= get_teb64(params32
->teb
),
1654 .sync
= (GLsync
)handle
->u
.context
,
1656 status
= ext_glDeleteSync( ¶ms
);
1657 free_handle_ptr( handle
);
1660 pthread_mutex_unlock( &wgl_lock
);
1664 NTSTATUS
wow64_ext_glFenceSync( void *args
)
1673 struct glFenceSync_params params
=
1675 .teb
= get_teb64(params32
->teb
),
1676 .condition
= params32
->condition
,
1677 .flags
= params32
->flags
,
1681 if ((status
= ext_glFenceSync( ¶ms
))) return status
;
1683 pthread_mutex_lock( &wgl_lock
);
1685 if (!(params32
->ret
= (UINT_PTR
)alloc_handle( HANDLE_GLSYNC
, NULL
, params
.ret
)))
1687 struct glDeleteSync_params delete_params
=
1693 ext_glDeleteSync( &delete_params
);
1694 status
= STATUS_NO_MEMORY
;
1697 pthread_mutex_unlock( &wgl_lock
);
1701 NTSTATUS
wow64_ext_glGetSynciv( void *args
)
1703 struct wgl_handle
*handle
;
1715 pthread_mutex_lock( &wgl_lock
);
1717 if (!(handle
= get_handle_ptr( ULongToPtr(params32
->sync
), HANDLE_GLSYNC
)))
1718 status
= STATUS_INVALID_HANDLE
;
1721 struct glGetSynciv_params params
=
1723 .teb
= get_teb64(params32
->teb
),
1724 .sync
= (GLsync
)handle
->u
.context
,
1725 .pname
= params32
->pname
,
1726 .count
= params32
->count
,
1727 .length
= ULongToPtr(params32
->length
),
1728 .values
= ULongToPtr(params32
->values
),
1730 status
= ext_glGetSynciv( ¶ms
);
1733 pthread_mutex_unlock( &wgl_lock
);
1737 NTSTATUS
wow64_ext_glIsSync( void *args
)
1739 struct wgl_handle
*handle
;
1748 pthread_mutex_lock( &wgl_lock
);
1750 if (!(handle
= get_handle_ptr( ULongToPtr(params32
->sync
), HANDLE_GLSYNC
)))
1751 status
= STATUS_INVALID_HANDLE
;
1754 struct glIsSync_params params
=
1756 .teb
= get_teb64(params32
->teb
),
1757 .sync
= (GLsync
)handle
->u
.context
,
1759 status
= ext_glIsSync( ¶ms
);
1760 params32
->ret
= params
.ret
;
1763 pthread_mutex_unlock( &wgl_lock
);
1767 NTSTATUS
wow64_ext_glWaitSync( void *args
)
1769 struct wgl_handle
*handle
;
1779 pthread_mutex_lock( &wgl_lock
);
1781 if (!(handle
= get_handle_ptr( ULongToPtr(params32
->sync
), HANDLE_GLSYNC
)))
1782 status
= STATUS_INVALID_HANDLE
;
1785 struct glWaitSync_params params
=
1787 .teb
= get_teb64(params32
->teb
),
1788 .sync
= (GLsync
)handle
->u
.context
,
1789 .flags
= params32
->flags
,
1790 .timeout
= params32
->timeout
,
1792 status
= ext_glWaitSync( ¶ms
);
1795 pthread_mutex_unlock( &wgl_lock
);
1799 static GLint
get_buffer_param( TEB
*teb
, GLenum target
, GLenum param
)
1801 const struct opengl_funcs
*funcs
= teb
->glTable
;
1802 typeof(*funcs
->ext
.p_glGetBufferParameteriv
) *func
;
1804 if (!(func
= funcs
->ext
.p_glGetBufferParameteriv
)) func
= (void *)funcs
->wgl
.p_wglGetProcAddress( "glGetBufferParameteriv" );
1805 if (func
) func( target
, param
, &size
);
1809 static void *get_buffer_pointer( TEB
*teb
, GLenum target
)
1811 const struct opengl_funcs
*funcs
= teb
->glTable
;
1812 typeof(*funcs
->ext
.p_glGetBufferPointerv
) *func
;
1814 if (!(func
= funcs
->ext
.p_glGetBufferPointerv
)) func
= (void *)funcs
->wgl
.p_wglGetProcAddress( "glGetBufferPointerv" );
1815 if (func
) func( target
, GL_BUFFER_MAP_POINTER
, &ptr
);
1819 static GLint
get_named_buffer_param( TEB
*teb
, GLint buffer
, GLenum param
)
1821 const struct opengl_funcs
*funcs
= teb
->glTable
;
1822 typeof(*funcs
->ext
.p_glGetNamedBufferParameteriv
) *func
;
1824 if (!(func
= funcs
->ext
.p_glGetNamedBufferParameteriv
)) func
= (void *)funcs
->wgl
.p_wglGetProcAddress( "glGetNamedBufferParameteriv" );
1825 if (func
) func( buffer
, param
, &size
);
1829 static void *get_named_buffer_pointer( TEB
*teb
, GLint buffer
)
1831 const struct opengl_funcs
*funcs
= teb
->glTable
;
1832 typeof(*funcs
->ext
.p_glGetNamedBufferPointerv
) *func
;
1834 if (!(func
= funcs
->ext
.p_glGetNamedBufferPointerv
)) func
= (void *)funcs
->wgl
.p_wglGetProcAddress( "glGetNamedBufferPointerv" );
1835 if (func
) func( buffer
, GL_BUFFER_MAP_POINTER
, &ptr
);
1839 static void unmap_buffer( TEB
*teb
, GLenum target
)
1841 const struct opengl_funcs
*funcs
= teb
->glTable
;
1842 typeof(*funcs
->ext
.p_glUnmapBuffer
) *func
;
1843 if (!(func
= funcs
->ext
.p_glUnmapBuffer
)) func
= (void *)funcs
->wgl
.p_wglGetProcAddress( "glUnmapBuffer" );
1844 if (func
) func( target
);
1847 static void unmap_named_buffer( TEB
*teb
, GLint buffer
)
1849 const struct opengl_funcs
*funcs
= teb
->glTable
;
1850 typeof(*funcs
->ext
.p_glUnmapNamedBuffer
) *func
;
1851 if (!(func
= funcs
->ext
.p_glUnmapNamedBuffer
)) func
= (void *)funcs
->wgl
.p_wglGetProcAddress( "glUnmapNamedBuffer" );
1852 if (func
) func( buffer
);
1855 static NTSTATUS
wow64_map_buffer( TEB
*teb
, GLint buffer
, GLenum target
, void *ptr
, SIZE_T size
,
1856 GLbitfield access
, PTR32
*ret
)
1858 if (*ret
) /* wow64 pointer provided, map buffer to it */
1860 if (!(access
& (GL_MAP_INVALIDATE_RANGE_BIT
| GL_MAP_INVALIDATE_BUFFER_BIT
)))
1862 TRACE( "Copying %#zx from buffer at %p to wow64 buffer %p\n", size
, ptr
, UlongToPtr(*ret
) );
1863 memcpy( UlongToPtr(*ret
), ptr
, size
);
1866 /* save the wow64 pointer in the buffer data, we'll overwrite it on unmap */
1867 *(PTR32
*)ptr
= (UINT_PTR
)*ret
;
1868 return STATUS_SUCCESS
;
1871 if (ULongToPtr(*ret
= PtrToUlong(ptr
)) == ptr
) return STATUS_SUCCESS
; /* we're lucky */
1872 if (access
& GL_MAP_PERSISTENT_BIT
)
1874 FIXME( "GL_MAP_PERSISTENT_BIT not supported!\n" );
1875 return STATUS_NOT_SUPPORTED
;
1878 if (!size
) size
= buffer
? get_named_buffer_param( teb
, buffer
, GL_BUFFER_SIZE
) : get_buffer_param( teb
, target
, GL_BUFFER_SIZE
);
1879 if ((PTR32
)size
!= size
) return STATUS_NO_MEMORY
; /* overflow */
1880 if (size
< sizeof(PTR32
))
1882 FIXME( "Buffer too small for metadata!\n" );
1883 return STATUS_BUFFER_TOO_SMALL
;
1887 return STATUS_INVALID_ADDRESS
;
1890 static GLbitfield
map_range_flags_from_map_flags( GLenum flags
)
1894 case GL_READ_ONLY
: return GL_MAP_READ_BIT
;
1895 case GL_WRITE_ONLY
: return GL_MAP_WRITE_BIT
;
1896 case GL_READ_WRITE
: return GL_MAP_READ_BIT
| GL_MAP_WRITE_BIT
;
1898 ERR( "invalid map flags %#x\n", flags
);
1899 return GL_MAP_READ_BIT
| GL_MAP_WRITE_BIT
;
1903 static NTSTATUS
wow64_unmap_buffer( void *ptr
, SIZE_T size
, GLbitfield access
)
1907 if (ULongToPtr(PtrToUlong(ptr
)) == ptr
) return STATUS_SUCCESS
; /* we're lucky */
1909 wow_ptr
= UlongToPtr(*(PTR32
*)ptr
);
1910 if (access
& GL_MAP_WRITE_BIT
)
1912 TRACE( "Copying %#zx from wow64 buffer %p to buffer %p\n", size
, wow_ptr
, ptr
);
1913 memcpy( ptr
, wow_ptr
, size
);
1916 return STATUS_INVALID_ADDRESS
;
1919 static NTSTATUS
wow64_gl_get_buffer_pointer_v( void *args
, NTSTATUS (*get_buffer_pointer_v64
)(void *) )
1921 PTR32
*ptr
; /* pointer to the buffer data, where we saved the wow64 pointer */
1929 struct glGetBufferPointerv_params params
=
1931 .teb
= get_teb64(params32
->teb
),
1932 .target
= params32
->target
,
1933 .pname
= params32
->pname
,
1934 .params
= (void **)&ptr
,
1936 PTR32
*wow_ptr
= UlongToPtr(params32
->params
);
1939 if ((status
= get_buffer_pointer_v64( ¶ms
))) return status
;
1940 if (params
.pname
!= GL_BUFFER_MAP_POINTER
) return STATUS_NOT_IMPLEMENTED
;
1941 if (ULongToPtr(*wow_ptr
= PtrToUlong(ptr
)) == ptr
) return STATUS_SUCCESS
; /* we're lucky */
1943 return STATUS_SUCCESS
;
1946 NTSTATUS
wow64_ext_glGetBufferPointerv( void *args
)
1948 return wow64_gl_get_buffer_pointer_v( args
, ext_glGetBufferPointerv
);
1951 NTSTATUS
wow64_ext_glGetBufferPointervARB( void *args
)
1953 return wow64_gl_get_buffer_pointer_v( args
, ext_glGetBufferPointervARB
);
1956 static NTSTATUS
wow64_gl_get_named_buffer_pointer_v( void *args
, NTSTATUS (*gl_get_named_buffer_pointer_v64
)(void *) )
1958 PTR32
*ptr
; /* pointer to the buffer data, where we saved the wow64 pointer */
1966 struct glGetNamedBufferPointerv_params params
=
1968 .teb
= get_teb64(params32
->teb
),
1969 .buffer
= params32
->buffer
,
1970 .pname
= params32
->pname
,
1971 .params
= (void **)&ptr
,
1973 PTR32
*wow_ptr
= UlongToPtr(params32
->params
);
1976 if ((status
= gl_get_named_buffer_pointer_v64( ¶ms
))) return status
;
1977 if (params
.pname
!= GL_BUFFER_MAP_POINTER
) return STATUS_NOT_IMPLEMENTED
;
1978 if (ULongToPtr(*wow_ptr
= PtrToUlong(ptr
)) == ptr
) return STATUS_SUCCESS
; /* we're lucky */
1980 return STATUS_SUCCESS
;
1983 NTSTATUS
wow64_ext_glGetNamedBufferPointerv( void *args
)
1985 return wow64_gl_get_named_buffer_pointer_v( args
, ext_glGetNamedBufferPointerv
);
1988 NTSTATUS
wow64_ext_glGetNamedBufferPointervEXT( void *args
)
1990 return wow64_gl_get_named_buffer_pointer_v( args
, ext_glGetNamedBufferPointervEXT
);
1993 static NTSTATUS
wow64_gl_map_buffer( void *args
, NTSTATUS (*gl_map_buffer64
)(void *) )
2002 struct glMapBuffer_params params
=
2004 .teb
= get_teb64(params32
->teb
),
2005 .target
= params32
->target
,
2006 .access
= params32
->access
,
2010 /* already mapped, we're being called again with a wow64 pointer */
2011 if (params32
->ret
) params
.ret
= get_buffer_pointer( params
.teb
, params
.target
);
2012 else if ((status
= gl_map_buffer64( ¶ms
))) return status
;
2014 status
= wow64_map_buffer( params
.teb
, 0, params
.target
, params
.ret
, 0,
2015 map_range_flags_from_map_flags( params
.access
), ¶ms32
->ret
);
2016 if (!status
|| status
== STATUS_INVALID_ADDRESS
) return status
;
2018 unmap_buffer( params
.teb
, params
.target
);
2022 NTSTATUS
wow64_ext_glMapBuffer( void *args
)
2024 return wow64_gl_map_buffer( args
, ext_glMapBuffer
);
2027 NTSTATUS
wow64_ext_glMapBufferARB( void *args
)
2029 return wow64_gl_map_buffer( args
, ext_glMapBufferARB
);
2032 NTSTATUS
wow64_ext_glMapBufferRange( void *args
)
2043 struct glMapBufferRange_params params
=
2045 .teb
= get_teb64(params32
->teb
),
2046 .target
= params32
->target
,
2047 .offset
= (GLintptr
)ULongToPtr(params32
->offset
),
2048 .length
= (GLsizeiptr
)ULongToPtr(params32
->length
),
2049 .access
= params32
->access
,
2053 /* already mapped, we're being called again with a wow64 pointer */
2054 if (params32
->ret
) params
.ret
= (char *)get_buffer_pointer( params
.teb
, params
.target
);
2055 else if ((status
= ext_glMapBufferRange( ¶ms
))) return status
;
2057 status
= wow64_map_buffer( params
.teb
, 0, params
.target
, params
.ret
, params
.length
, params
.access
, ¶ms32
->ret
);
2058 if (!status
|| status
== STATUS_INVALID_ADDRESS
) return status
;
2060 unmap_buffer( params
.teb
, params
.target
);
2064 static NTSTATUS
wow64_gl_map_named_buffer( void *args
, NTSTATUS (*gl_map_named_buffer64
)(void *) )
2073 struct glMapNamedBuffer_params params
=
2075 .teb
= get_teb64(params32
->teb
),
2076 .buffer
= params32
->buffer
,
2077 .access
= params32
->access
,
2081 /* already mapped, we're being called again with a wow64 pointer */
2082 if (params32
->ret
) params
.ret
= get_named_buffer_pointer( params
.teb
, params
.buffer
);
2083 else if ((status
= gl_map_named_buffer64( ¶ms
))) return status
;
2085 status
= wow64_map_buffer( params
.teb
, params
.buffer
, 0, params
.ret
, 0,
2086 map_range_flags_from_map_flags( params
.access
), ¶ms32
->ret
);
2087 if (!status
|| status
== STATUS_INVALID_ADDRESS
) return status
;
2089 unmap_named_buffer( params
.teb
, params
.buffer
);
2093 NTSTATUS
wow64_ext_glMapNamedBuffer( void *args
)
2095 return wow64_gl_map_named_buffer( args
, ext_glMapNamedBuffer
);
2098 NTSTATUS
wow64_ext_glMapNamedBufferEXT( void *args
)
2100 return wow64_gl_map_named_buffer( args
, ext_glMapNamedBufferEXT
);
2103 static NTSTATUS
wow64_gl_map_named_buffer_range( void *args
, NTSTATUS (*gl_map_named_buffer_range64
)(void *) )
2114 struct glMapNamedBufferRange_params params
=
2116 .teb
= get_teb64(params32
->teb
),
2117 .buffer
= params32
->buffer
,
2118 .offset
= (GLintptr
)ULongToPtr(params32
->offset
),
2119 .length
= (GLsizeiptr
)ULongToPtr(params32
->length
),
2120 .access
= params32
->access
,
2124 /* already mapped, we're being called again with a wow64 pointer */
2125 if (params32
->ret
) params
.ret
= get_named_buffer_pointer( params
.teb
, params
.buffer
);
2126 else if ((status
= gl_map_named_buffer_range64( ¶ms
))) return status
;
2128 status
= wow64_map_buffer( params
.teb
, params
.buffer
, 0, params
.ret
, params
.length
, params
.access
, ¶ms32
->ret
);
2129 if (!status
|| status
== STATUS_INVALID_ADDRESS
) return status
;
2131 unmap_named_buffer( params
.teb
, params
.buffer
);
2135 NTSTATUS
wow64_ext_glMapNamedBufferRange( void *args
)
2137 return wow64_gl_map_named_buffer_range( args
, ext_glMapNamedBufferRange
);
2140 NTSTATUS
wow64_ext_glMapNamedBufferRangeEXT( void *args
)
2142 return wow64_gl_map_named_buffer_range( args
, ext_glMapNamedBufferRangeEXT
);
2145 static NTSTATUS
wow64_gl_unmap_buffer( void *args
, NTSTATUS (*gl_unmap_buffer64
)(void *) )
2154 struct glUnmapBuffer_params params
=
2156 .teb
= get_teb64(params32
->teb
),
2157 .target
= params32
->target
,
2162 if (!(ptr
= get_buffer_pointer( params
.teb
, params
.target
))) return STATUS_SUCCESS
;
2164 status
= wow64_unmap_buffer( ptr
, get_buffer_param( params
.teb
, params
.target
, GL_BUFFER_MAP_LENGTH
),
2165 get_buffer_param( params
.teb
, params
.target
, GL_BUFFER_ACCESS_FLAGS
) );
2166 gl_unmap_buffer64( ¶ms
);
2167 params32
->ret
= params
.ret
;
2172 NTSTATUS
wow64_ext_glUnmapBuffer( void *args
)
2174 return wow64_gl_unmap_buffer( args
, ext_glUnmapBuffer
);
2177 NTSTATUS
wow64_ext_glUnmapBufferARB( void *args
)
2179 return wow64_gl_unmap_buffer( args
, ext_glUnmapBufferARB
);
2182 static NTSTATUS
wow64_gl_unmap_named_buffer( void *args
, NTSTATUS (*gl_unmap_named_buffer64
)(void *) )
2191 struct glUnmapNamedBuffer_params params
=
2193 .teb
= get_teb64(params32
->teb
),
2194 .buffer
= params32
->buffer
,
2199 if (!(ptr
= get_named_buffer_pointer( params
.teb
, params
.buffer
))) return STATUS_SUCCESS
;
2201 status
= wow64_unmap_buffer( ptr
, get_named_buffer_param( params
.teb
, params
.buffer
, GL_BUFFER_MAP_LENGTH
),
2202 get_named_buffer_param( params
.teb
, params
.buffer
, GL_BUFFER_ACCESS_FLAGS
) );
2203 gl_unmap_named_buffer64( ¶ms
);
2204 params32
->ret
= params
.ret
;
2209 NTSTATUS
wow64_ext_glUnmapNamedBuffer( void *args
)
2211 return wow64_gl_unmap_named_buffer( args
, ext_glUnmapNamedBuffer
);
2214 NTSTATUS
wow64_ext_glUnmapNamedBufferEXT( void *args
)
2216 return wow64_gl_unmap_named_buffer( args
, ext_glUnmapNamedBufferEXT
);
2219 NTSTATUS
wow64_thread_attach( void *args
)
2221 return thread_attach( get_teb64( (ULONG_PTR
)args
));
2224 NTSTATUS
wow64_process_detach( void *args
)
2228 if ((status
= process_detach( NULL
))) return status
;
2230 free( wow64_strings
);
2231 wow64_strings
= NULL
;
2232 wow64_strings_count
= 0;
2234 return STATUS_SUCCESS
;