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 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
, 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 GLuint
*filter_extensions_index( TEB
*teb
, const char *disabled
)
203 const struct opengl_funcs
*funcs
= teb
->glTable
;
204 GLuint
*disabled_index
;
205 GLint extensions_count
;
206 unsigned int i
= 0, j
;
209 if (!funcs
->ext
.p_glGetStringi
)
211 void **func_ptr
= (void **)&funcs
->ext
.p_glGetStringi
;
212 *func_ptr
= funcs
->wgl
.p_wglGetProcAddress( "glGetStringi" );
213 if (!funcs
->ext
.p_glGetStringi
) return NULL
;
216 funcs
->gl
.p_glGetIntegerv( GL_NUM_EXTENSIONS
, &extensions_count
);
217 disabled_index
= malloc( extensions_count
* sizeof(*disabled_index
) );
218 if (!disabled_index
) return NULL
;
220 TRACE( "GL_EXTENSIONS:\n" );
222 for (j
= 0; j
< extensions_count
; ++j
)
224 ext
= (const char *)funcs
->ext
.p_glGetStringi( GL_EXTENSIONS
, j
);
226 /* We do not support GL_MAP_PERSISTENT_BIT, and hence
227 * ARB_buffer_storage, on wow64. */
228 if (is_win64
&& is_wow64() && (!strcmp( ext
, "GL_ARB_buffer_storage" ) || !strcmp( ext
, "GL_EXT_buffer_storage" )))
230 TRACE( "-- %s (disabled due to wow64)\n", ext
);
231 disabled_index
[i
++] = j
;
233 else if (!has_extension( disabled
, ext
, strlen( ext
) ))
235 TRACE( "++ %s\n", ext
);
239 TRACE( "-- %s (disabled by config)\n", ext
);
240 disabled_index
[i
++] = j
;
244 disabled_index
[i
] = ~0u;
245 return disabled_index
;
248 static inline void ascii_to_unicode( WCHAR
*dst
, const char *src
, size_t len
)
250 while (len
--) *dst
++ = (unsigned char)*src
++;
253 static inline UINT
asciiz_to_unicode( WCHAR
*dst
, const char *src
)
256 while ((*p
++ = *src
++));
257 return (p
- dst
) * sizeof(WCHAR
);
260 static inline void unicode_to_ascii( char *dst
, const WCHAR
*src
, size_t len
)
262 while (len
--) *dst
++ = *src
++;
265 static HKEY
reg_open_key( HKEY root
, const WCHAR
*name
, ULONG name_len
)
267 UNICODE_STRING nameW
= { name_len
, name_len
, (WCHAR
*)name
};
268 OBJECT_ATTRIBUTES attr
;
271 attr
.Length
= sizeof(attr
);
272 attr
.RootDirectory
= root
;
273 attr
.ObjectName
= &nameW
;
275 attr
.SecurityDescriptor
= NULL
;
276 attr
.SecurityQualityOfService
= NULL
;
278 return NtOpenKeyEx( &ret
, MAXIMUM_ALLOWED
, &attr
, 0 ) ? 0 : ret
;
281 static HKEY
open_hkcu_key( const char *name
)
289 DWORD_PTR sid_data
[(sizeof(TOKEN_USER
) + SECURITY_MAX_SID_SIZE
) / sizeof(DWORD_PTR
)];
290 DWORD i
, len
= sizeof(sid_data
);
293 if (NtQueryInformationToken( GetCurrentThreadEffectiveToken(), TokenUser
, sid_data
, len
, &len
))
296 sid
= ((TOKEN_USER
*)sid_data
)->User
.Sid
;
297 len
= sprintf( buffer
, "\\Registry\\User\\S-%u-%u", sid
->Revision
,
298 (int)MAKELONG( MAKEWORD( sid
->IdentifierAuthority
.Value
[5],
299 sid
->IdentifierAuthority
.Value
[4] ),
300 MAKEWORD( sid
->IdentifierAuthority
.Value
[3],
301 sid
->IdentifierAuthority
.Value
[2] )));
302 for (i
= 0; i
< sid
->SubAuthorityCount
; i
++)
303 len
+= sprintf( buffer
+ len
, "-%u", (int)sid
->SubAuthority
[i
] );
305 ascii_to_unicode( bufferW
, buffer
, len
);
306 hkcu
= reg_open_key( NULL
, bufferW
, len
* sizeof(WCHAR
) );
309 return reg_open_key( hkcu
, bufferW
, asciiz_to_unicode( bufferW
, name
) - sizeof(WCHAR
) );
312 static NTSTATUS
query_reg_value( HKEY hkey
, const WCHAR
*name
, KEY_VALUE_PARTIAL_INFORMATION
*info
, ULONG size
)
314 unsigned int name_size
= name
? lstrlenW( name
) * sizeof(WCHAR
) : 0;
315 UNICODE_STRING nameW
= { name_size
, name_size
, (WCHAR
*)name
};
317 return NtQueryValueKey( hkey
, &nameW
, KeyValuePartialInformation
, info
, size
, &size
);
320 /* build the extension string by filtering out the disabled extensions */
321 static BOOL
filter_extensions( TEB
* teb
, const char *extensions
, GLubyte
**exts_list
, GLuint
**disabled_exts
)
323 static const char *disabled
;
330 /* @@ Wine registry key: HKCU\Software\Wine\OpenGL */
331 if ((hkey
= open_hkcu_key( "Software\\Wine\\OpenGL" )))
334 KEY_VALUE_PARTIAL_INFORMATION
*value
= (void *)buffer
;
335 static WCHAR disabled_extensionsW
[] = {'D','i','s','a','b','l','e','d','E','x','t','e','n','s','i','o','n','s',0};
337 if (!query_reg_value( hkey
, disabled_extensionsW
, value
, sizeof(buffer
) ))
339 ULONG len
= value
->DataLength
/ sizeof(WCHAR
);
341 unicode_to_ascii( buffer
, (WCHAR
*)value
->Data
, len
);
343 str
= strdup( buffer
);
349 if (InterlockedCompareExchangePointer( (void **)&disabled
, str
, NULL
)) free( str
);
354 if (extensions
&& !*exts_list
) *exts_list
= filter_extensions_list( extensions
, disabled
);
355 if (!*disabled_exts
) *disabled_exts
= filter_extensions_index( teb
, disabled
);
356 return (exts_list
&& *exts_list
) || *disabled_exts
;
359 static const GLuint
*disabled_extensions_index( TEB
*teb
)
361 struct wgl_handle
*ptr
= get_current_context_ptr( teb
);
362 GLuint
**disabled
= &ptr
->u
.context
->disabled_exts
;
363 if (*disabled
|| filter_extensions( teb
, NULL
, NULL
, disabled
)) return *disabled
;
367 /* Check if a GL extension is supported */
368 static BOOL
check_extension_support( TEB
*teb
, const char *extension
, const char *available_extensions
)
370 const struct opengl_funcs
*funcs
= teb
->glTable
;
373 TRACE( "Checking for extension '%s'\n", extension
);
375 /* We use the GetProcAddress function from the display driver to retrieve function pointers
376 * for OpenGL and WGL extensions. In case of winex11.drv the OpenGL extension lookup is done
377 * using glXGetProcAddress. This function is quite unreliable in the sense that its specs don't
378 * require the function to return NULL when an extension isn't found. For this reason we check
379 * if the OpenGL extension required for the function we are looking up is supported. */
381 while ((len
= strcspn( extension
, " " )))
383 /* Check if the extension is part of the GL extension string to see if it is supported. */
384 if (has_extension( available_extensions
, extension
, len
)) return TRUE
;
386 /* In general an OpenGL function starts as an ARB/EXT extension and at some stage
387 * it becomes part of the core OpenGL library and can be reached without the ARB/EXT
388 * suffix as well. In the extension table, these functions contain GL_VERSION_major_minor.
389 * Check if we are searching for a core GL function */
390 if (!strncmp( extension
, "GL_VERSION_", 11 ))
392 const GLubyte
*gl_version
= funcs
->gl
.p_glGetString( GL_VERSION
);
393 const char *version
= extension
+ 11; /* Move past 'GL_VERSION_' */
397 ERR( "No OpenGL version found!\n" );
401 /* Compare the major/minor version numbers of the native OpenGL library and what is required by the function.
402 * The gl_version string is guaranteed to have at least a major/minor and sometimes it has a release number as well. */
403 if ((gl_version
[0] > version
[0]) || ((gl_version
[0] == version
[0]) && (gl_version
[2] >= version
[2]))) return TRUE
;
405 WARN( "The function requires OpenGL version '%c.%c' while your drivers only provide '%c.%c'\n",
406 version
[0], version
[2], gl_version
[0], gl_version
[2] );
409 if (extension
[len
] == ' ') len
++;
416 static const char *parse_gl_version( const char *gl_version
, int *major
, int *minor
)
418 const char *ptr
= gl_version
;
420 *major
= atoi( ptr
);
422 ERR( "Invalid OpenGL major version %d.\n", *major
);
424 while (isdigit( *ptr
)) ++ptr
;
426 ERR( "Invalid OpenGL version string %s.\n", debugstr_a(gl_version
) );
428 *minor
= atoi( ptr
);
430 while (isdigit( *ptr
)) ++ptr
;
434 static void wrap_glGetIntegerv( TEB
*teb
, GLenum pname
, GLint
*data
)
436 const struct opengl_funcs
*funcs
= teb
->glTable
;
437 const GLuint
*disabled
;
439 funcs
->gl
.p_glGetIntegerv( pname
, data
);
441 if (pname
== GL_NUM_EXTENSIONS
&& (disabled
= disabled_extensions_index( teb
)))
442 while (*disabled
++ != ~0u) (*data
)--;
444 if (is_win64
&& is_wow64())
446 /* 4.4 depends on ARB_buffer_storage, which we don't support on wow64. */
447 if (pname
== GL_MAJOR_VERSION
&& *data
> 4)
449 else if (pname
== GL_MINOR_VERSION
)
453 funcs
->gl
.p_glGetIntegerv( GL_MAJOR_VERSION
, &major
);
454 if (major
== 4 && *data
> 3)
460 static const GLubyte
*wrap_glGetString( TEB
*teb
, GLenum name
)
462 const struct opengl_funcs
*funcs
= teb
->glTable
;
465 if ((ret
= funcs
->gl
.p_glGetString( name
)))
467 if (name
== GL_EXTENSIONS
)
469 struct wgl_handle
*ptr
= get_current_context_ptr( teb
);
470 GLubyte
**extensions
= &ptr
->u
.context
->extensions
;
471 GLuint
**disabled
= &ptr
->u
.context
->disabled_exts
;
472 if (*extensions
|| filter_extensions( teb
, (const char *)ret
, extensions
, disabled
)) return *extensions
;
474 else if (name
== GL_VERSION
&& is_win64
&& is_wow64())
476 struct wgl_handle
*ptr
= get_current_context_ptr( teb
);
480 if (ptr
->u
.context
->version_string
)
481 return ptr
->u
.context
->version_string
;
483 rest
= parse_gl_version( (const char *)ret
, &major
, &minor
);
485 /* 4.4 depends on ARB_buffer_storage, which we don't support on wow64. */
486 if (major
> 4 || (major
== 4 && minor
>= 4))
488 char *str
= malloc( 3 + strlen( rest
) + 1 );
490 sprintf( str
, "4.3%s", rest
);
491 if (InterlockedCompareExchangePointer( (void **)&ptr
->u
.context
->version_string
, str
, NULL
))
493 return ptr
->u
.context
->version_string
;
501 static const GLubyte
*wrap_glGetStringi( TEB
*teb
, GLenum name
, GLuint index
)
503 const struct opengl_funcs
*funcs
= teb
->glTable
;
504 const GLuint
*disabled
;
506 if (!funcs
->ext
.p_glGetStringi
)
508 void **func_ptr
= (void **)&funcs
->ext
.p_glGetStringi
;
509 *func_ptr
= funcs
->wgl
.p_wglGetProcAddress( "glGetStringi" );
512 if (name
== GL_EXTENSIONS
&& (disabled
= disabled_extensions_index( teb
)))
513 while (index
>= *disabled
++) index
++;
515 return funcs
->ext
.p_glGetStringi( name
, index
);
518 static char *build_extension_list( TEB
*teb
)
520 GLint len
= 0, capacity
, i
, extensions_count
;
521 char *extension
, *tmp
, *available_extensions
;
523 wrap_glGetIntegerv( teb
, GL_NUM_EXTENSIONS
, &extensions_count
);
524 capacity
= 128 * extensions_count
;
526 if (!(available_extensions
= malloc( capacity
))) return NULL
;
527 for (i
= 0; i
< extensions_count
; ++i
)
529 extension
= (char *)wrap_glGetStringi( teb
, GL_EXTENSIONS
, i
);
530 capacity
= max( capacity
, len
+ strlen( extension
) + 2 );
531 if (!(tmp
= realloc( available_extensions
, capacity
))) break;
532 available_extensions
= tmp
;
533 len
+= sprintf( available_extensions
+ len
, "%s ", extension
);
535 if (len
) available_extensions
[len
- 1] = 0;
537 return available_extensions
;
540 static inline enum wgl_handle_type
get_current_context_type( TEB
*teb
)
542 if (!teb
->glCurrentRC
) return HANDLE_CONTEXT
;
543 return LOWORD(teb
->glCurrentRC
) & HANDLE_TYPE_MASK
;
546 /* Check if a GL extension is supported */
547 static BOOL
is_extension_supported( TEB
*teb
, const char *extension
)
549 enum wgl_handle_type type
= get_current_context_type( teb
);
550 char *available_extensions
= NULL
;
553 if (type
== HANDLE_CONTEXT
) available_extensions
= strdup( (const char *)wrap_glGetString( teb
, GL_EXTENSIONS
) );
554 if (!available_extensions
) available_extensions
= build_extension_list( teb
);
556 if (!available_extensions
) ERR( "No OpenGL extensions found, check if your OpenGL setup is correct!\n" );
557 else ret
= check_extension_support( teb
, extension
, available_extensions
);
559 free( available_extensions
);
563 static int registry_entry_cmp( const void *a
, const void *b
)
565 const struct registry_entry
*entry_a
= a
, *entry_b
= b
;
566 return strcmp( entry_a
->name
, entry_b
->name
);
569 static PROC
wrap_wglGetProcAddress( TEB
*teb
, LPCSTR name
)
571 const struct registry_entry entry
= {.name
= name
}, *found
;
572 struct opengl_funcs
*funcs
= teb
->glTable
;
573 const void **func_ptr
;
575 /* Without an active context opengl32 doesn't know to what
576 * driver it has to dispatch wglGetProcAddress.
578 if (!get_current_context_ptr( teb
))
580 WARN( "No active WGL context found\n" );
584 if (!(found
= bsearch( &entry
, extension_registry
, extension_registry_size
, sizeof(entry
), registry_entry_cmp
)))
586 WARN( "Function %s unknown\n", name
);
590 func_ptr
= (const void **)&funcs
->ext
+ (found
- extension_registry
);
593 void *driver_func
= funcs
->wgl
.p_wglGetProcAddress( name
);
595 if (!is_extension_supported( teb
, found
->extension
))
598 static const struct { const char *name
, *alt
; } alternatives
[] =
600 { "glCopyTexSubImage3DEXT", "glCopyTexSubImage3D" }, /* needed by RuneScape */
601 { "glVertexAttribDivisor", "glVertexAttribDivisorARB"}, /* needed by Caffeine */
604 for (i
= 0; i
< ARRAY_SIZE(alternatives
); i
++)
606 if (strcmp( name
, alternatives
[i
].name
)) continue;
607 WARN( "Extension %s required for %s not supported, trying %s\n", found
->extension
,
608 name
, alternatives
[i
].alt
);
609 return wrap_wglGetProcAddress( teb
, alternatives
[i
].alt
);
612 WARN( "Extension %s required for %s not supported\n", found
->extension
, name
);
616 if (driver_func
== NULL
)
618 WARN( "Function %s not supported by driver\n", name
);
622 *func_ptr
= driver_func
;
625 /* Return the index into the extension registry instead of a useless
626 * function pointer, PE side will returns its own function pointers.
628 return (void *)(UINT_PTR
)(found
- extension_registry
);
631 static BOOL
wrap_wglCopyContext( HGLRC hglrcSrc
, HGLRC hglrcDst
, UINT mask
)
633 struct wgl_handle
*src
, *dst
;
636 if (!(src
= get_handle_ptr( hglrcSrc
, HANDLE_CONTEXT
))) return FALSE
;
637 if ((dst
= get_handle_ptr( hglrcDst
, HANDLE_CONTEXT
)))
639 if (src
->funcs
!= dst
->funcs
) RtlSetLastWin32Error( ERROR_INVALID_HANDLE
);
640 else ret
= src
->funcs
->wgl
.p_wglCopyContext( src
->u
.context
->drv_ctx
, dst
->u
.context
->drv_ctx
, mask
);
645 static HGLRC
wrap_wglCreateContext( HDC hdc
)
648 struct wgl_context
*drv_ctx
;
649 struct opengl_context
*context
;
650 struct opengl_funcs
*funcs
= get_dc_funcs( hdc
);
652 if (!funcs
) return 0;
653 if (!(drv_ctx
= funcs
->wgl
.p_wglCreateContext( hdc
))) return 0;
654 if ((context
= calloc( 1, sizeof(*context
) )))
656 context
->drv_ctx
= drv_ctx
;
657 if (!(ret
= alloc_handle( HANDLE_CONTEXT
, funcs
, context
))) free( context
);
659 if (!ret
) funcs
->wgl
.p_wglDeleteContext( drv_ctx
);
663 static BOOL
wrap_wglMakeCurrent( TEB
*teb
, HDC hdc
, HGLRC hglrc
)
666 DWORD tid
= HandleToULong(teb
->ClientId
.UniqueThread
);
667 struct wgl_handle
*ptr
, *prev
= get_current_context_ptr( teb
);
671 if (!(ptr
= get_handle_ptr( hglrc
, HANDLE_CONTEXT
))) return FALSE
;
672 if (!ptr
->u
.context
->tid
|| ptr
->u
.context
->tid
== tid
)
674 ret
= ptr
->funcs
->wgl
.p_wglMakeCurrent( hdc
, ptr
->u
.context
->drv_ctx
);
677 if (prev
) prev
->u
.context
->tid
= 0;
678 ptr
->u
.context
->tid
= tid
;
679 teb
->glReserved1
[0] = hdc
;
680 teb
->glReserved1
[1] = hdc
;
681 teb
->glCurrentRC
= hglrc
;
682 teb
->glTable
= ptr
->funcs
;
687 RtlSetLastWin32Error( ERROR_BUSY
);
693 if (!prev
->funcs
->wgl
.p_wglMakeCurrent( 0, NULL
)) return FALSE
;
694 prev
->u
.context
->tid
= 0;
695 teb
->glCurrentRC
= 0;
696 teb
->glTable
= &null_opengl_funcs
;
700 RtlSetLastWin32Error( ERROR_INVALID_HANDLE
);
706 static BOOL
wrap_wglDeleteContext( TEB
*teb
, HGLRC hglrc
)
708 struct wgl_handle
*ptr
;
709 DWORD tid
= HandleToULong(teb
->ClientId
.UniqueThread
);
711 if (!(ptr
= get_handle_ptr( hglrc
, HANDLE_CONTEXT
))) return FALSE
;
712 if (ptr
->u
.context
->tid
&& ptr
->u
.context
->tid
!= tid
)
714 RtlSetLastWin32Error( ERROR_BUSY
);
717 if (hglrc
== teb
->glCurrentRC
) wrap_wglMakeCurrent( teb
, 0, 0 );
718 ptr
->funcs
->wgl
.p_wglDeleteContext( ptr
->u
.context
->drv_ctx
);
719 free( ptr
->u
.context
->version_string
);
720 free( ptr
->u
.context
->disabled_exts
);
721 free( ptr
->u
.context
->extensions
);
722 free( ptr
->u
.context
);
723 free_handle_ptr( ptr
);
727 static BOOL
wrap_wglShareLists( HGLRC hglrcSrc
, HGLRC hglrcDst
)
730 struct wgl_handle
*src
, *dst
;
732 if (!(src
= get_handle_ptr( hglrcSrc
, HANDLE_CONTEXT
))) return FALSE
;
733 if ((dst
= get_handle_ptr( hglrcDst
, HANDLE_CONTEXT
)))
735 if (src
->funcs
!= dst
->funcs
) RtlSetLastWin32Error( ERROR_INVALID_HANDLE
);
736 else ret
= src
->funcs
->wgl
.p_wglShareLists( src
->u
.context
->drv_ctx
, dst
->u
.context
->drv_ctx
);
741 static BOOL
wrap_wglBindTexImageARB( HPBUFFERARB handle
, int buffer
)
743 struct wgl_handle
*ptr
;
744 if (!(ptr
= get_handle_ptr( handle
, HANDLE_PBUFFER
))) return FALSE
;
745 return ptr
->funcs
->ext
.p_wglBindTexImageARB( ptr
->u
.pbuffer
, buffer
);
748 static HGLRC
wrap_wglCreateContextAttribsARB( HDC hdc
, HGLRC share
, const int *attribs
)
751 struct wgl_context
*drv_ctx
;
752 struct wgl_handle
*share_ptr
= NULL
;
753 struct opengl_context
*context
;
754 struct opengl_funcs
*funcs
= get_dc_funcs( hdc
);
758 RtlSetLastWin32Error( ERROR_DC_NOT_FOUND
);
761 if (!funcs
->ext
.p_wglCreateContextAttribsARB
) return 0;
762 if (share
&& !(share_ptr
= get_handle_ptr( share
, HANDLE_CONTEXT
)))
764 RtlSetLastWin32Error( ERROR_INVALID_OPERATION
);
767 if ((drv_ctx
= funcs
->ext
.p_wglCreateContextAttribsARB( hdc
, share_ptr
? share_ptr
->u
.context
->drv_ctx
: NULL
, attribs
)))
769 if ((context
= calloc( 1, sizeof(*context
) )))
771 enum wgl_handle_type type
= HANDLE_CONTEXT
;
777 if (attribs
[0] == WGL_CONTEXT_MAJOR_VERSION_ARB
)
779 if (attribs
[1] >= 3) type
= HANDLE_CONTEXT_V3
;
786 context
->drv_ctx
= drv_ctx
;
787 if (!(ret
= alloc_handle( type
, funcs
, context
))) free( context
);
789 if (!ret
) funcs
->wgl
.p_wglDeleteContext( drv_ctx
);
795 static HPBUFFERARB
wrap_wglCreatePbufferARB( HDC hdc
, int format
, int width
, int height
, const int *attribs
)
798 struct wgl_pbuffer
*pbuffer
;
799 struct opengl_funcs
*funcs
= get_dc_funcs( hdc
);
801 if (!funcs
|| !funcs
->ext
.p_wglCreatePbufferARB
) return 0;
802 if (!(pbuffer
= funcs
->ext
.p_wglCreatePbufferARB( hdc
, format
, width
, height
, attribs
))) return 0;
803 ret
= alloc_handle( HANDLE_PBUFFER
, funcs
, pbuffer
);
804 if (!ret
) funcs
->ext
.p_wglDestroyPbufferARB( pbuffer
);
808 static BOOL
wrap_wglDestroyPbufferARB( HPBUFFERARB handle
)
810 struct wgl_handle
*ptr
;
812 if (!(ptr
= get_handle_ptr( handle
, HANDLE_PBUFFER
))) return FALSE
;
813 ptr
->funcs
->ext
.p_wglDestroyPbufferARB( ptr
->u
.pbuffer
);
814 free_handle_ptr( ptr
);
818 static HDC
wrap_wglGetPbufferDCARB( HPBUFFERARB handle
)
820 struct wgl_handle
*ptr
;
821 if (!(ptr
= get_handle_ptr( handle
, HANDLE_PBUFFER
))) return 0;
822 return ptr
->funcs
->ext
.p_wglGetPbufferDCARB( ptr
->u
.pbuffer
);
825 static BOOL
wrap_wglMakeContextCurrentARB( TEB
*teb
, HDC draw_hdc
, HDC read_hdc
, HGLRC hglrc
)
828 DWORD tid
= HandleToULong(teb
->ClientId
.UniqueThread
);
829 struct wgl_handle
*ptr
, *prev
= get_current_context_ptr( teb
);
833 if (!(ptr
= get_handle_ptr( hglrc
, HANDLE_CONTEXT
))) return FALSE
;
834 if (!ptr
->u
.context
->tid
|| ptr
->u
.context
->tid
== tid
)
836 ret
= (ptr
->funcs
->ext
.p_wglMakeContextCurrentARB
&&
837 ptr
->funcs
->ext
.p_wglMakeContextCurrentARB( draw_hdc
, read_hdc
, ptr
->u
.context
->drv_ctx
));
840 if (prev
) prev
->u
.context
->tid
= 0;
841 ptr
->u
.context
->tid
= tid
;
842 teb
->glReserved1
[0] = draw_hdc
;
843 teb
->glReserved1
[1] = read_hdc
;
844 teb
->glCurrentRC
= hglrc
;
845 teb
->glTable
= ptr
->funcs
;
850 RtlSetLastWin32Error( ERROR_BUSY
);
856 if (!prev
->funcs
->wgl
.p_wglMakeCurrent( 0, NULL
)) return FALSE
;
857 prev
->u
.context
->tid
= 0;
858 teb
->glCurrentRC
= 0;
859 teb
->glTable
= &null_opengl_funcs
;
864 static BOOL
wrap_wglQueryPbufferARB( HPBUFFERARB handle
, int attrib
, int *value
)
866 struct wgl_handle
*ptr
;
867 if (!(ptr
= get_handle_ptr( handle
, HANDLE_PBUFFER
))) return FALSE
;
868 return ptr
->funcs
->ext
.p_wglQueryPbufferARB( ptr
->u
.pbuffer
, attrib
, value
);
871 static int wrap_wglReleasePbufferDCARB( HPBUFFERARB handle
, HDC hdc
)
873 struct wgl_handle
*ptr
;
874 if (!(ptr
= get_handle_ptr( handle
, HANDLE_PBUFFER
))) return FALSE
;
875 return ptr
->funcs
->ext
.p_wglReleasePbufferDCARB( ptr
->u
.pbuffer
, hdc
);
878 static BOOL
wrap_wglReleaseTexImageARB( HPBUFFERARB handle
, int buffer
)
880 struct wgl_handle
*ptr
;
881 if (!(ptr
= get_handle_ptr( handle
, HANDLE_PBUFFER
))) return FALSE
;
882 return ptr
->funcs
->ext
.p_wglReleaseTexImageARB( ptr
->u
.pbuffer
, buffer
);
885 static BOOL
wrap_wglSetPbufferAttribARB( HPBUFFERARB handle
, const int *attribs
)
887 struct wgl_handle
*ptr
;
888 if (!(ptr
= get_handle_ptr( handle
, HANDLE_PBUFFER
))) return FALSE
;
889 return ptr
->funcs
->ext
.p_wglSetPbufferAttribARB( ptr
->u
.pbuffer
, attribs
);
892 static void gl_debug_message_callback( GLenum source
, GLenum type
, GLuint id
, GLenum severity
,
893 GLsizei length
, const GLchar
*message
, const void *userParam
)
895 struct wine_gl_debug_message_params params
=
900 .severity
= severity
,
906 struct wgl_handle
*ptr
= (struct wgl_handle
*)userParam
;
910 fprintf( stderr
, "msg:gl_debug_message_callback called from native thread, severity %#x, message \"%.*s\".\n",
911 severity
, length
, message
);
915 if (!(params
.user_callback
= ptr
->u
.context
->debug_callback
)) return;
916 params
.user_data
= ptr
->u
.context
->debug_user
;
918 KeUserModeCallback( NtUserCallOpenGLDebugMessageCallback
, ¶ms
, sizeof(params
),
919 &ret_ptr
, &ret_len
);
922 static void wrap_glDebugMessageCallback( TEB
*teb
, GLDEBUGPROC callback
, const void *userParam
)
924 struct wgl_handle
*ptr
= get_current_context_ptr( teb
);
925 const struct opengl_funcs
*funcs
= teb
->glTable
;
927 if (!funcs
->ext
.p_glDebugMessageCallback
) return;
929 ptr
->u
.context
->debug_callback
= callback
;
930 ptr
->u
.context
->debug_user
= userParam
;
931 funcs
->ext
.p_glDebugMessageCallback( gl_debug_message_callback
, ptr
);
934 static void wrap_glDebugMessageCallbackAMD( TEB
*teb
, GLDEBUGPROCAMD callback
, void *userParam
)
936 struct wgl_handle
*ptr
= get_current_context_ptr( teb
);
937 const struct opengl_funcs
*funcs
= teb
->glTable
;
939 if (!funcs
->ext
.p_glDebugMessageCallbackAMD
) return;
941 ptr
->u
.context
->debug_callback
= callback
;
942 ptr
->u
.context
->debug_user
= userParam
;
943 funcs
->ext
.p_glDebugMessageCallbackAMD( gl_debug_message_callback
, ptr
);
946 static void wrap_glDebugMessageCallbackARB( TEB
*teb
, GLDEBUGPROCARB callback
, const void *userParam
)
948 struct wgl_handle
*ptr
= get_current_context_ptr( teb
);
949 const struct opengl_funcs
*funcs
= teb
->glTable
;
951 if (!funcs
->ext
.p_glDebugMessageCallbackARB
) return;
953 ptr
->u
.context
->debug_callback
= callback
;
954 ptr
->u
.context
->debug_user
= userParam
;
955 funcs
->ext
.p_glDebugMessageCallbackARB( gl_debug_message_callback
, ptr
);
958 NTSTATUS
wgl_wglCopyContext( void *args
)
960 struct wglCopyContext_params
*params
= args
;
961 pthread_mutex_lock( &wgl_lock
);
962 params
->ret
= wrap_wglCopyContext( params
->hglrcSrc
, params
->hglrcDst
, params
->mask
);
963 pthread_mutex_unlock( &wgl_lock
);
964 return STATUS_SUCCESS
;
967 NTSTATUS
wgl_wglCreateContext( void *args
)
969 struct wglCreateContext_params
*params
= args
;
970 pthread_mutex_lock( &wgl_lock
);
971 params
->ret
= wrap_wglCreateContext( params
->hDc
);
972 pthread_mutex_unlock( &wgl_lock
);
973 return STATUS_SUCCESS
;
976 NTSTATUS
wgl_wglDeleteContext( void *args
)
978 struct wglDeleteContext_params
*params
= args
;
979 pthread_mutex_lock( &wgl_lock
);
980 params
->ret
= wrap_wglDeleteContext( params
->teb
, params
->oldContext
);
981 pthread_mutex_unlock( &wgl_lock
);
982 return STATUS_SUCCESS
;
985 NTSTATUS
wgl_wglGetProcAddress( void *args
)
987 struct wglGetProcAddress_params
*params
= args
;
988 params
->ret
= wrap_wglGetProcAddress( params
->teb
, params
->lpszProc
);
989 return STATUS_SUCCESS
;
992 NTSTATUS
wgl_wglMakeCurrent( void *args
)
994 struct wglMakeCurrent_params
*params
= args
;
995 if (params
->newContext
) pthread_mutex_lock( &wgl_lock
);
996 params
->ret
= wrap_wglMakeCurrent( params
->teb
, params
->hDc
, params
->newContext
);
997 if (params
->newContext
) pthread_mutex_unlock( &wgl_lock
);
998 return STATUS_SUCCESS
;
1001 NTSTATUS
wgl_wglShareLists( void *args
)
1003 struct wglShareLists_params
*params
= args
;
1004 pthread_mutex_lock( &wgl_lock
);
1005 params
->ret
= wrap_wglShareLists( params
->hrcSrvShare
, params
->hrcSrvSource
);
1006 pthread_mutex_unlock( &wgl_lock
);
1007 return STATUS_SUCCESS
;
1010 NTSTATUS
gl_glGetIntegerv( void *args
)
1012 struct glGetIntegerv_params
*params
= args
;
1013 wrap_glGetIntegerv( params
->teb
, params
->pname
, params
->data
);
1014 return STATUS_SUCCESS
;
1017 NTSTATUS
gl_glGetString( void *args
)
1019 struct glGetString_params
*params
= args
;
1020 params
->ret
= wrap_glGetString( params
->teb
, params
->name
);
1021 return STATUS_SUCCESS
;
1024 NTSTATUS
ext_glDebugMessageCallback( void *args
)
1026 struct glDebugMessageCallback_params
*params
= args
;
1027 wrap_glDebugMessageCallback( params
->teb
, params
->callback
, params
->userParam
);
1028 return STATUS_SUCCESS
;
1031 NTSTATUS
ext_glDebugMessageCallbackAMD( void *args
)
1033 struct glDebugMessageCallbackAMD_params
*params
= args
;
1034 wrap_glDebugMessageCallbackAMD( params
->teb
, params
->callback
, params
->userParam
);
1035 return STATUS_SUCCESS
;
1038 NTSTATUS
ext_glDebugMessageCallbackARB( void *args
)
1040 struct glDebugMessageCallbackARB_params
*params
= args
;
1041 wrap_glDebugMessageCallbackARB( params
->teb
, params
->callback
, params
->userParam
);
1042 return STATUS_SUCCESS
;
1045 NTSTATUS
ext_glGetStringi( void *args
)
1047 struct glGetStringi_params
*params
= args
;
1048 params
->ret
= wrap_glGetStringi( params
->teb
, params
->name
, params
->index
);
1049 return STATUS_SUCCESS
;
1052 NTSTATUS
ext_wglBindTexImageARB( void *args
)
1054 struct wglBindTexImageARB_params
*params
= args
;
1055 pthread_mutex_lock( &wgl_lock
);
1056 params
->ret
= wrap_wglBindTexImageARB( params
->hPbuffer
, params
->iBuffer
);
1057 pthread_mutex_unlock( &wgl_lock
);
1058 return STATUS_SUCCESS
;
1061 NTSTATUS
ext_wglCreateContextAttribsARB( void *args
)
1063 struct wglCreateContextAttribsARB_params
*params
= args
;
1064 pthread_mutex_lock( &wgl_lock
);
1065 params
->ret
= wrap_wglCreateContextAttribsARB( params
->hDC
, params
->hShareContext
, params
->attribList
);
1066 pthread_mutex_unlock( &wgl_lock
);
1067 return STATUS_SUCCESS
;
1070 NTSTATUS
ext_wglCreatePbufferARB( void *args
)
1072 struct wglCreatePbufferARB_params
*params
= args
;
1073 pthread_mutex_lock( &wgl_lock
);
1074 params
->ret
= wrap_wglCreatePbufferARB( params
->hDC
, params
->iPixelFormat
, params
->iWidth
, params
->iHeight
, params
->piAttribList
);
1075 pthread_mutex_unlock( &wgl_lock
);
1076 return STATUS_SUCCESS
;
1079 NTSTATUS
ext_wglDestroyPbufferARB( void *args
)
1081 struct wglDestroyPbufferARB_params
*params
= args
;
1082 pthread_mutex_lock( &wgl_lock
);
1083 params
->ret
= wrap_wglDestroyPbufferARB( params
->hPbuffer
);
1084 pthread_mutex_unlock( &wgl_lock
);
1085 return STATUS_SUCCESS
;
1088 NTSTATUS
ext_wglGetPbufferDCARB( void *args
)
1090 struct wglGetPbufferDCARB_params
*params
= args
;
1091 pthread_mutex_lock( &wgl_lock
);
1092 params
->ret
= wrap_wglGetPbufferDCARB( params
->hPbuffer
);
1093 pthread_mutex_unlock( &wgl_lock
);
1094 return STATUS_SUCCESS
;
1097 NTSTATUS
ext_wglMakeContextCurrentARB( void *args
)
1099 struct wglMakeContextCurrentARB_params
*params
= args
;
1100 if (params
->hglrc
) pthread_mutex_lock( &wgl_lock
);
1101 params
->ret
= wrap_wglMakeContextCurrentARB( params
->teb
, params
->hDrawDC
, params
->hReadDC
, params
->hglrc
);
1102 if (params
->hglrc
) pthread_mutex_unlock( &wgl_lock
);
1103 return STATUS_SUCCESS
;
1106 NTSTATUS
ext_wglQueryPbufferARB( void *args
)
1108 struct wglQueryPbufferARB_params
*params
= args
;
1109 pthread_mutex_lock( &wgl_lock
);
1110 params
->ret
= wrap_wglQueryPbufferARB( params
->hPbuffer
, params
->iAttribute
, params
->piValue
);
1111 pthread_mutex_unlock( &wgl_lock
);
1112 return STATUS_SUCCESS
;
1115 NTSTATUS
ext_wglReleasePbufferDCARB( void *args
)
1117 struct wglReleasePbufferDCARB_params
*params
= args
;
1118 pthread_mutex_lock( &wgl_lock
);
1119 params
->ret
= wrap_wglReleasePbufferDCARB( params
->hPbuffer
, params
->hDC
);
1120 pthread_mutex_unlock( &wgl_lock
);
1121 return STATUS_SUCCESS
;
1124 NTSTATUS
ext_wglReleaseTexImageARB( void *args
)
1126 struct wglReleaseTexImageARB_params
*params
= args
;
1127 pthread_mutex_lock( &wgl_lock
);
1128 params
->ret
= wrap_wglReleaseTexImageARB( params
->hPbuffer
, params
->iBuffer
);
1129 pthread_mutex_unlock( &wgl_lock
);
1130 return STATUS_SUCCESS
;
1133 NTSTATUS
ext_wglSetPbufferAttribARB( void *args
)
1135 struct wglSetPbufferAttribARB_params
*params
= args
;
1136 pthread_mutex_lock( &wgl_lock
);
1137 params
->ret
= wrap_wglSetPbufferAttribARB( params
->hPbuffer
, params
->piAttribList
);
1138 pthread_mutex_unlock( &wgl_lock
);
1139 return STATUS_SUCCESS
;
1142 NTSTATUS
thread_attach( void *args
)
1145 teb
->glTable
= &null_opengl_funcs
;
1146 return STATUS_SUCCESS
;
1149 NTSTATUS
process_detach( void *args
)
1151 return STATUS_SUCCESS
;
1156 typedef ULONG PTR32
;
1158 extern NTSTATUS
ext_glClientWaitSync( void *args
) DECLSPEC_HIDDEN
;
1159 extern NTSTATUS
ext_glDeleteSync( void *args
) DECLSPEC_HIDDEN
;
1160 extern NTSTATUS
ext_glFenceSync( void *args
) DECLSPEC_HIDDEN
;
1161 extern NTSTATUS
ext_glGetBufferPointerv( void *args
) DECLSPEC_HIDDEN
;
1162 extern NTSTATUS
ext_glGetBufferPointervARB( void *args
) DECLSPEC_HIDDEN
;
1163 extern NTSTATUS
ext_glGetNamedBufferPointerv( void *args
) DECLSPEC_HIDDEN
;
1164 extern NTSTATUS
ext_glGetNamedBufferPointervEXT( void *args
) DECLSPEC_HIDDEN
;
1165 extern NTSTATUS
ext_glGetSynciv( void *args
) DECLSPEC_HIDDEN
;
1166 extern NTSTATUS
ext_glIsSync( void *args
) DECLSPEC_HIDDEN
;
1167 extern NTSTATUS
ext_glMapBuffer( void *args
) DECLSPEC_HIDDEN
;
1169 extern NTSTATUS
ext_glUnmapBuffer( void *args
) DECLSPEC_HIDDEN
;
1170 extern NTSTATUS
ext_glUnmapBufferARB( void *args
) DECLSPEC_HIDDEN
;
1171 extern NTSTATUS
ext_glUnmapNamedBuffer( void *args
) DECLSPEC_HIDDEN
;
1172 extern NTSTATUS
ext_glUnmapNamedBufferEXT( void *args
) DECLSPEC_HIDDEN
;
1174 extern NTSTATUS
ext_glMapBufferARB( void *args
) DECLSPEC_HIDDEN
;
1175 extern NTSTATUS
ext_glMapBufferRange( void *args
) DECLSPEC_HIDDEN
;
1176 extern NTSTATUS
ext_glMapNamedBuffer( void *args
) DECLSPEC_HIDDEN
;
1177 extern NTSTATUS
ext_glMapNamedBufferEXT( void *args
) DECLSPEC_HIDDEN
;
1178 extern NTSTATUS
ext_glMapNamedBufferRange( void *args
) DECLSPEC_HIDDEN
;
1179 extern NTSTATUS
ext_glMapNamedBufferRangeEXT( void *args
) DECLSPEC_HIDDEN
;
1180 extern NTSTATUS
ext_glPathGlyphIndexRangeNV( void *args
) DECLSPEC_HIDDEN
;
1181 extern NTSTATUS
ext_glWaitSync( void *args
) DECLSPEC_HIDDEN
;
1182 extern NTSTATUS
ext_wglGetExtensionsStringARB( void *args
) DECLSPEC_HIDDEN
;
1183 extern NTSTATUS
ext_wglGetExtensionsStringEXT( void *args
) DECLSPEC_HIDDEN
;
1184 extern NTSTATUS
ext_wglQueryCurrentRendererStringWINE( void *args
) DECLSPEC_HIDDEN
;
1185 extern NTSTATUS
ext_wglQueryRendererStringWINE( void *args
) DECLSPEC_HIDDEN
;
1187 struct wow64_string_entry
1192 static struct wow64_string_entry
*wow64_strings
;
1193 static SIZE_T wow64_strings_count
;
1195 static PTR32
find_wow64_string( const char *str
, PTR32 wow64_str
)
1200 pthread_mutex_lock( &wgl_lock
);
1202 for (i
= 0; i
< wow64_strings_count
; i
++) if (wow64_strings
[i
].str
== str
) break;
1203 if (i
== wow64_strings_count
&& (tmp
= realloc( wow64_strings
, (i
+ 1) * sizeof(*wow64_strings
) )))
1205 wow64_strings
= tmp
;
1206 wow64_strings
[i
].str
= str
;
1207 wow64_strings
[i
].wow64_str
= 0;
1208 wow64_strings_count
+= 1;
1211 if (i
== wow64_strings_count
) ERR( "Failed to allocate memory for wow64 strings\n" );
1212 else if (wow64_strings
[i
].wow64_str
) wow64_str
= wow64_strings
[i
].wow64_str
;
1215 strcpy( UlongToPtr(wow64_str
), (char *)str
);
1216 wow64_strings
[i
].wow64_str
= wow64_str
;
1219 pthread_mutex_unlock( &wgl_lock
);
1224 static inline void update_teb32_context( TEB
*teb
)
1228 if (!teb
->WowTebOffset
) return;
1229 teb32
= (char *)teb
+ teb
->WowTebOffset
;
1231 ((TEB32
*)teb32
)->glCurrentRC
= (UINT_PTR
)teb
->glCurrentRC
;
1232 ((TEB32
*)teb32
)->glReserved1
[0] = (UINT_PTR
)teb
->glReserved1
[0];
1233 ((TEB32
*)teb32
)->glReserved1
[1] = (UINT_PTR
)teb
->glReserved1
[1];
1236 NTSTATUS
wow64_wgl_wglCreateContext( void *args
)
1244 struct wglCreateContext_params params
=
1246 .teb
= get_teb64(params32
->teb
),
1247 .hDc
= ULongToPtr(params32
->hDc
),
1250 if ((status
= wgl_wglCreateContext( ¶ms
))) return status
;
1251 params32
->ret
= (UINT_PTR
)params
.ret
;
1252 return STATUS_SUCCESS
;
1255 NTSTATUS
wow64_ext_wglCreateContextAttribsARB( void *args
)
1261 PTR32 hShareContext
;
1265 struct wglCreateContextAttribsARB_params params
=
1267 .teb
= get_teb64(params32
->teb
),
1268 .hDC
= ULongToPtr(params32
->hDC
),
1269 .hShareContext
= ULongToPtr(params32
->hShareContext
),
1270 .attribList
= ULongToPtr(params32
->attribList
),
1273 if ((status
= ext_wglCreateContextAttribsARB( ¶ms
))) return status
;
1274 params32
->ret
= (UINT_PTR
)params
.ret
;
1275 return STATUS_SUCCESS
;
1278 NTSTATUS
wow64_ext_wglCreatePbufferARB( void *args
)
1290 struct wglCreatePbufferARB_params params
=
1292 .teb
= get_teb64(params32
->teb
),
1293 .hDC
= ULongToPtr(params32
->hDC
),
1294 .iPixelFormat
= params32
->iPixelFormat
,
1295 .iWidth
= params32
->iWidth
,
1296 .iHeight
= params32
->iHeight
,
1297 .piAttribList
= ULongToPtr(params32
->piAttribList
),
1300 if ((status
= ext_wglCreatePbufferARB( ¶ms
))) return status
;
1301 params32
->ret
= (UINT_PTR
)params
.ret
;
1302 return STATUS_SUCCESS
;
1305 NTSTATUS
wow64_wgl_wglDeleteContext( void *args
)
1313 struct wglDeleteContext_params params
=
1315 .teb
= get_teb64(params32
->teb
),
1316 .oldContext
= ULongToPtr(params32
->oldContext
),
1319 if (!(status
= wgl_wglDeleteContext( ¶ms
))) update_teb32_context( params
.teb
);
1320 params32
->ret
= params
.ret
;
1324 NTSTATUS
wow64_wgl_wglMakeCurrent( void *args
)
1333 struct wglMakeCurrent_params params
=
1335 .teb
= get_teb64(params32
->teb
),
1336 .hDc
= ULongToPtr(params32
->hDc
),
1337 .newContext
= ULongToPtr(params32
->newContext
),
1340 if (!(status
= wgl_wglMakeCurrent( ¶ms
))) update_teb32_context( params
.teb
);
1341 params32
->ret
= params
.ret
;
1345 NTSTATUS
wow64_ext_wglMakeContextCurrentARB( void *args
)
1355 struct wglMakeContextCurrentARB_params params
=
1357 .teb
= get_teb64(params32
->teb
),
1358 .hDrawDC
= ULongToPtr(params32
->hDrawDC
),
1359 .hReadDC
= ULongToPtr(params32
->hReadDC
),
1360 .hglrc
= ULongToPtr(params32
->hglrc
),
1363 if (!(status
= ext_wglMakeContextCurrentARB( ¶ms
))) update_teb32_context( params
.teb
);
1364 params32
->ret
= params
.ret
;
1368 NTSTATUS
wow64_ext_wglGetPbufferDCARB( void *args
)
1376 struct wglGetPbufferDCARB_params params
=
1378 .teb
= get_teb64(params32
->teb
),
1379 .hPbuffer
= (HPBUFFERARB
)ULongToPtr(params32
->hPbuffer
),
1382 if ((status
= ext_wglGetPbufferDCARB( ¶ms
))) return status
;
1383 params32
->ret
= (UINT_PTR
)params
.ret
;
1384 return STATUS_SUCCESS
;
1387 NTSTATUS
wow64_wgl_wglGetProcAddress( void *args
)
1395 struct wglGetProcAddress_params params
=
1397 .teb
= get_teb64(params32
->teb
),
1398 .lpszProc
= ULongToPtr(params32
->lpszProc
),
1401 if ((status
= wgl_wglGetProcAddress( ¶ms
))) return status
;
1402 params32
->ret
= (UINT_PTR
)params
.ret
;
1403 return STATUS_SUCCESS
;
1406 NTSTATUS
wow64_gl_glGetString( void *args
)
1414 struct glGetString_params params
=
1416 .teb
= get_teb64(params32
->teb
),
1417 .name
= params32
->name
,
1421 if ((status
= gl_glGetString( ¶ms
))) return status
;
1423 if (!(params32
->ret
= find_wow64_string( (char *)params
.ret
, params32
->ret
)))
1425 params32
->ret
= strlen( (char *)params
.ret
) + 1;
1426 return STATUS_BUFFER_TOO_SMALL
;
1429 return STATUS_SUCCESS
;
1432 NTSTATUS
wow64_ext_glGetStringi( void *args
)
1441 struct glGetStringi_params params
=
1443 .teb
= get_teb64(params32
->teb
),
1444 .name
= params32
->name
,
1445 .index
= params32
->index
,
1449 if ((status
= ext_glGetStringi( ¶ms
))) return status
;
1451 if (!(params32
->ret
= find_wow64_string( (char *)params
.ret
, params32
->ret
)))
1453 params32
->ret
= strlen( (char *)params
.ret
) + 1;
1454 return STATUS_BUFFER_TOO_SMALL
;
1457 return STATUS_SUCCESS
;
1460 NTSTATUS
wow64_ext_glPathGlyphIndexRangeNV( void *args
)
1467 GLbitfield fontStyle
;
1468 GLuint pathParameterTemplate
;
1470 GLuint baseAndCount
[2];
1473 struct glPathGlyphIndexRangeNV_params params
=
1475 .teb
= get_teb64(params32
->teb
),
1476 .fontTarget
= params32
->fontTarget
,
1477 .fontName
= ULongToPtr(params32
->fontName
),
1478 .fontStyle
= params32
->fontStyle
,
1479 .pathParameterTemplate
= params32
->pathParameterTemplate
,
1480 .emScale
= params32
->emScale
,
1481 .baseAndCount
= {params32
->baseAndCount
[0], params32
->baseAndCount
[1]},
1484 if ((status
= ext_glPathGlyphIndexRangeNV( ¶ms
))) return status
;
1485 params32
->ret
= params
.ret
;
1489 NTSTATUS
wow64_ext_wglGetExtensionsStringARB( void *args
)
1497 struct wglGetExtensionsStringARB_params params
=
1499 .teb
= get_teb64(params32
->teb
),
1500 .hdc
= ULongToPtr(params32
->hdc
),
1504 if ((status
= ext_wglGetExtensionsStringARB( ¶ms
))) return status
;
1506 if (!(params32
->ret
= find_wow64_string( params
.ret
, params32
->ret
)))
1508 params32
->ret
= strlen( params
.ret
) + 1;
1509 return STATUS_BUFFER_TOO_SMALL
;
1512 return STATUS_SUCCESS
;
1515 NTSTATUS
wow64_ext_wglGetExtensionsStringEXT( void *args
)
1522 struct wglGetExtensionsStringEXT_params params
=
1524 .teb
= get_teb64(params32
->teb
),
1528 if ((status
= ext_wglGetExtensionsStringEXT( ¶ms
))) return status
;
1530 if (!(params32
->ret
= find_wow64_string( params
.ret
, params32
->ret
)))
1532 params32
->ret
= strlen( params
.ret
) + 1;
1533 return STATUS_BUFFER_TOO_SMALL
;
1536 return STATUS_SUCCESS
;
1539 NTSTATUS
wow64_ext_wglQueryCurrentRendererStringWINE( void *args
)
1547 struct wglQueryCurrentRendererStringWINE_params params
=
1549 .teb
= get_teb64(params32
->teb
),
1550 .attribute
= params32
->attribute
,
1554 if ((status
= ext_wglQueryCurrentRendererStringWINE( ¶ms
))) return status
;
1556 if (!(params32
->ret
= find_wow64_string( params
.ret
, params32
->ret
)))
1558 params32
->ret
= strlen( params
.ret
) + 1;
1559 return STATUS_BUFFER_TOO_SMALL
;
1562 return STATUS_SUCCESS
;
1565 NTSTATUS
wow64_ext_wglQueryRendererStringWINE( void *args
)
1575 struct wglQueryRendererStringWINE_params params
=
1577 .teb
= get_teb64(params32
->teb
),
1578 .dc
= ULongToPtr(params32
->dc
),
1579 .renderer
= params32
->renderer
,
1580 .attribute
= params32
->attribute
,
1584 if ((status
= ext_wglQueryRendererStringWINE( ¶ms
))) return status
;
1586 if (!(params32
->ret
= find_wow64_string( params
.ret
, params32
->ret
)))
1588 params32
->ret
= strlen( params
.ret
) + 1;
1589 return STATUS_BUFFER_TOO_SMALL
;
1592 return STATUS_SUCCESS
;
1595 NTSTATUS
wow64_ext_glClientWaitSync( void *args
)
1597 struct wgl_handle
*handle
;
1608 pthread_mutex_lock( &wgl_lock
);
1610 if (!(handle
= get_handle_ptr( ULongToPtr(params32
->sync
), HANDLE_GLSYNC
)))
1611 status
= STATUS_INVALID_HANDLE
;
1614 struct glClientWaitSync_params params
=
1616 .teb
= get_teb64(params32
->teb
),
1617 .sync
= (GLsync
)handle
->u
.context
,
1618 .flags
= params32
->flags
,
1619 .timeout
= params32
->timeout
,
1621 status
= ext_glClientWaitSync( ¶ms
);
1622 params32
->ret
= params
.ret
;
1625 pthread_mutex_unlock( &wgl_lock
);
1629 NTSTATUS
wow64_ext_glDeleteSync( void *args
)
1631 struct wgl_handle
*handle
;
1639 pthread_mutex_lock( &wgl_lock
);
1641 if (!(handle
= get_handle_ptr( ULongToPtr(params32
->sync
), HANDLE_GLSYNC
)))
1642 status
= STATUS_INVALID_HANDLE
;
1645 struct glDeleteSync_params params
=
1647 .teb
= get_teb64(params32
->teb
),
1648 .sync
= (GLsync
)handle
->u
.context
,
1650 status
= ext_glDeleteSync( ¶ms
);
1651 free_handle_ptr( handle
);
1654 pthread_mutex_unlock( &wgl_lock
);
1658 NTSTATUS
wow64_ext_glFenceSync( void *args
)
1667 struct glFenceSync_params params
=
1669 .teb
= get_teb64(params32
->teb
),
1670 .condition
= params32
->condition
,
1671 .flags
= params32
->flags
,
1675 if ((status
= ext_glFenceSync( ¶ms
))) return status
;
1677 pthread_mutex_lock( &wgl_lock
);
1679 if (!(params32
->ret
= (UINT_PTR
)alloc_handle( HANDLE_GLSYNC
, NULL
, params
.ret
)))
1681 struct glDeleteSync_params delete_params
=
1687 ext_glDeleteSync( &delete_params
);
1688 status
= STATUS_NO_MEMORY
;
1691 pthread_mutex_unlock( &wgl_lock
);
1695 NTSTATUS
wow64_ext_glGetSynciv( void *args
)
1697 struct wgl_handle
*handle
;
1709 pthread_mutex_lock( &wgl_lock
);
1711 if (!(handle
= get_handle_ptr( ULongToPtr(params32
->sync
), HANDLE_GLSYNC
)))
1712 status
= STATUS_INVALID_HANDLE
;
1715 struct glGetSynciv_params params
=
1717 .teb
= get_teb64(params32
->teb
),
1718 .sync
= (GLsync
)handle
->u
.context
,
1719 .pname
= params32
->pname
,
1720 .count
= params32
->count
,
1721 .length
= ULongToPtr(params32
->length
),
1722 .values
= ULongToPtr(params32
->values
),
1724 status
= ext_glGetSynciv( ¶ms
);
1727 pthread_mutex_unlock( &wgl_lock
);
1731 NTSTATUS
wow64_ext_glIsSync( void *args
)
1733 struct wgl_handle
*handle
;
1742 pthread_mutex_lock( &wgl_lock
);
1744 if (!(handle
= get_handle_ptr( ULongToPtr(params32
->sync
), HANDLE_GLSYNC
)))
1745 status
= STATUS_INVALID_HANDLE
;
1748 struct glIsSync_params params
=
1750 .teb
= get_teb64(params32
->teb
),
1751 .sync
= (GLsync
)handle
->u
.context
,
1753 status
= ext_glIsSync( ¶ms
);
1754 params32
->ret
= params
.ret
;
1757 pthread_mutex_unlock( &wgl_lock
);
1761 NTSTATUS
wow64_ext_glWaitSync( void *args
)
1763 struct wgl_handle
*handle
;
1773 pthread_mutex_lock( &wgl_lock
);
1775 if (!(handle
= get_handle_ptr( ULongToPtr(params32
->sync
), HANDLE_GLSYNC
)))
1776 status
= STATUS_INVALID_HANDLE
;
1779 struct glWaitSync_params params
=
1781 .teb
= get_teb64(params32
->teb
),
1782 .sync
= (GLsync
)handle
->u
.context
,
1783 .flags
= params32
->flags
,
1784 .timeout
= params32
->timeout
,
1786 status
= ext_glWaitSync( ¶ms
);
1789 pthread_mutex_unlock( &wgl_lock
);
1793 static GLint
get_buffer_param( TEB
*teb
, GLenum target
, GLenum param
)
1795 const struct opengl_funcs
*funcs
= teb
->glTable
;
1796 typeof(*funcs
->ext
.p_glGetBufferParameteriv
) *func
;
1798 if (!(func
= funcs
->ext
.p_glGetBufferParameteriv
)) func
= (void *)funcs
->wgl
.p_wglGetProcAddress( "glGetBufferParameteriv" );
1799 if (func
) func( target
, param
, &size
);
1803 static void *get_buffer_pointer( TEB
*teb
, GLenum target
)
1805 const struct opengl_funcs
*funcs
= teb
->glTable
;
1806 typeof(*funcs
->ext
.p_glGetBufferPointerv
) *func
;
1808 if (!(func
= funcs
->ext
.p_glGetBufferPointerv
)) func
= (void *)funcs
->wgl
.p_wglGetProcAddress( "glGetBufferPointerv" );
1809 if (func
) func( target
, GL_BUFFER_MAP_POINTER
, &ptr
);
1813 static GLint
get_named_buffer_param( TEB
*teb
, GLint buffer
, GLenum param
)
1815 const struct opengl_funcs
*funcs
= teb
->glTable
;
1816 typeof(*funcs
->ext
.p_glGetNamedBufferParameteriv
) *func
;
1818 if (!(func
= funcs
->ext
.p_glGetNamedBufferParameteriv
)) func
= (void *)funcs
->wgl
.p_wglGetProcAddress( "glGetNamedBufferParameteriv" );
1819 if (func
) func( buffer
, param
, &size
);
1823 static void *get_named_buffer_pointer( TEB
*teb
, GLint buffer
)
1825 const struct opengl_funcs
*funcs
= teb
->glTable
;
1826 typeof(*funcs
->ext
.p_glGetNamedBufferPointerv
) *func
;
1828 if (!(func
= funcs
->ext
.p_glGetNamedBufferPointerv
)) func
= (void *)funcs
->wgl
.p_wglGetProcAddress( "glGetNamedBufferPointerv" );
1829 if (func
) func( buffer
, GL_BUFFER_MAP_POINTER
, &ptr
);
1833 static void unmap_buffer( TEB
*teb
, GLenum target
)
1835 const struct opengl_funcs
*funcs
= teb
->glTable
;
1836 typeof(*funcs
->ext
.p_glUnmapBuffer
) *func
;
1837 if (!(func
= funcs
->ext
.p_glUnmapBuffer
)) func
= (void *)funcs
->wgl
.p_wglGetProcAddress( "glUnmapBuffer" );
1838 if (func
) func( target
);
1841 static void unmap_named_buffer( TEB
*teb
, GLint buffer
)
1843 const struct opengl_funcs
*funcs
= teb
->glTable
;
1844 typeof(*funcs
->ext
.p_glUnmapNamedBuffer
) *func
;
1845 if (!(func
= funcs
->ext
.p_glUnmapNamedBuffer
)) func
= (void *)funcs
->wgl
.p_wglGetProcAddress( "glUnmapNamedBuffer" );
1846 if (func
) func( buffer
);
1849 static NTSTATUS
wow64_map_buffer( TEB
*teb
, GLint buffer
, GLenum target
, void *ptr
, SIZE_T size
,
1850 GLbitfield access
, PTR32
*ret
)
1852 if (*ret
) /* wow64 pointer provided, map buffer to it */
1854 if (!(access
& (GL_MAP_INVALIDATE_RANGE_BIT
| GL_MAP_INVALIDATE_BUFFER_BIT
)))
1856 TRACE( "Copying %#zx from buffer at %p to wow64 buffer %p\n", size
, ptr
, UlongToPtr(*ret
) );
1857 memcpy( UlongToPtr(*ret
), ptr
, size
);
1860 /* save the wow64 pointer in the buffer data, we'll overwrite it on unmap */
1861 *(PTR32
*)ptr
= (UINT_PTR
)*ret
;
1862 return STATUS_SUCCESS
;
1865 if (ULongToPtr(*ret
= PtrToUlong(ptr
)) == ptr
) return STATUS_SUCCESS
; /* we're lucky */
1866 if (access
& GL_MAP_PERSISTENT_BIT
)
1868 FIXME( "GL_MAP_PERSISTENT_BIT not supported!\n" );
1869 return STATUS_NOT_SUPPORTED
;
1872 if (!size
) size
= buffer
? get_named_buffer_param( teb
, buffer
, GL_BUFFER_SIZE
) : get_buffer_param( teb
, target
, GL_BUFFER_SIZE
);
1873 if ((PTR32
)size
!= size
) return STATUS_NO_MEMORY
; /* overflow */
1874 if (size
< sizeof(PTR32
))
1876 FIXME( "Buffer too small for metadata!\n" );
1877 return STATUS_BUFFER_TOO_SMALL
;
1881 return STATUS_INVALID_ADDRESS
;
1884 static GLbitfield
map_range_flags_from_map_flags( GLenum flags
)
1888 case GL_READ_ONLY
: return GL_MAP_READ_BIT
;
1889 case GL_WRITE_ONLY
: return GL_MAP_WRITE_BIT
;
1890 case GL_READ_WRITE
: return GL_MAP_READ_BIT
| GL_MAP_WRITE_BIT
;
1892 ERR( "invalid map flags %#x\n", flags
);
1893 return GL_MAP_READ_BIT
| GL_MAP_WRITE_BIT
;
1897 static NTSTATUS
wow64_unmap_buffer( void *ptr
, SIZE_T size
, GLbitfield access
)
1901 if (ULongToPtr(PtrToUlong(ptr
)) == ptr
) return STATUS_SUCCESS
; /* we're lucky */
1903 wow_ptr
= UlongToPtr(*(PTR32
*)ptr
);
1904 if (access
& GL_MAP_WRITE_BIT
)
1906 TRACE( "Copying %#zx from wow64 buffer %p to buffer %p\n", size
, wow_ptr
, ptr
);
1907 memcpy( ptr
, wow_ptr
, size
);
1910 return STATUS_INVALID_ADDRESS
;
1913 static NTSTATUS
wow64_gl_get_buffer_pointer_v( void *args
, NTSTATUS (*get_buffer_pointer_v64
)(void *) )
1915 PTR32
*ptr
; /* pointer to the buffer data, where we saved the wow64 pointer */
1923 struct glGetBufferPointerv_params params
=
1925 .teb
= get_teb64(params32
->teb
),
1926 .target
= params32
->target
,
1927 .pname
= params32
->pname
,
1928 .params
= (void **)&ptr
,
1930 PTR32
*wow_ptr
= UlongToPtr(params32
->params
);
1933 if ((status
= get_buffer_pointer_v64( ¶ms
))) return status
;
1934 if (params
.pname
!= GL_BUFFER_MAP_POINTER
) return STATUS_NOT_IMPLEMENTED
;
1935 if (ULongToPtr(*wow_ptr
= PtrToUlong(ptr
)) == ptr
) return STATUS_SUCCESS
; /* we're lucky */
1937 return STATUS_SUCCESS
;
1940 NTSTATUS
wow64_ext_glGetBufferPointerv( void *args
)
1942 return wow64_gl_get_buffer_pointer_v( args
, ext_glGetBufferPointerv
);
1945 NTSTATUS
wow64_ext_glGetBufferPointervARB( void *args
)
1947 return wow64_gl_get_buffer_pointer_v( args
, ext_glGetBufferPointervARB
);
1950 static NTSTATUS
wow64_gl_get_named_buffer_pointer_v( void *args
, NTSTATUS (*gl_get_named_buffer_pointer_v64
)(void *) )
1952 PTR32
*ptr
; /* pointer to the buffer data, where we saved the wow64 pointer */
1960 struct glGetNamedBufferPointerv_params params
=
1962 .teb
= get_teb64(params32
->teb
),
1963 .buffer
= params32
->buffer
,
1964 .pname
= params32
->pname
,
1965 .params
= (void **)&ptr
,
1967 PTR32
*wow_ptr
= UlongToPtr(params32
->params
);
1970 if ((status
= gl_get_named_buffer_pointer_v64( ¶ms
))) return status
;
1971 if (params
.pname
!= GL_BUFFER_MAP_POINTER
) return STATUS_NOT_IMPLEMENTED
;
1972 if (ULongToPtr(*wow_ptr
= PtrToUlong(ptr
)) == ptr
) return STATUS_SUCCESS
; /* we're lucky */
1974 return STATUS_SUCCESS
;
1977 NTSTATUS
wow64_ext_glGetNamedBufferPointerv( void *args
)
1979 return wow64_gl_get_named_buffer_pointer_v( args
, ext_glGetNamedBufferPointerv
);
1982 NTSTATUS
wow64_ext_glGetNamedBufferPointervEXT( void *args
)
1984 return wow64_gl_get_named_buffer_pointer_v( args
, ext_glGetNamedBufferPointervEXT
);
1987 static NTSTATUS
wow64_gl_map_buffer( void *args
, NTSTATUS (*gl_map_buffer64
)(void *) )
1996 struct glMapBuffer_params params
=
1998 .teb
= get_teb64(params32
->teb
),
1999 .target
= params32
->target
,
2000 .access
= params32
->access
,
2004 /* already mapped, we're being called again with a wow64 pointer */
2005 if (params32
->ret
) params
.ret
= get_buffer_pointer( params
.teb
, params
.target
);
2006 else if ((status
= gl_map_buffer64( ¶ms
))) return status
;
2008 status
= wow64_map_buffer( params
.teb
, 0, params
.target
, params
.ret
, 0,
2009 map_range_flags_from_map_flags( params
.access
), ¶ms32
->ret
);
2010 if (!status
|| status
== STATUS_INVALID_ADDRESS
) return status
;
2012 unmap_buffer( params
.teb
, params
.target
);
2016 NTSTATUS
wow64_ext_glMapBuffer( void *args
)
2018 return wow64_gl_map_buffer( args
, ext_glMapBuffer
);
2021 NTSTATUS
wow64_ext_glMapBufferARB( void *args
)
2023 return wow64_gl_map_buffer( args
, ext_glMapBufferARB
);
2026 NTSTATUS
wow64_ext_glMapBufferRange( void *args
)
2037 struct glMapBufferRange_params params
=
2039 .teb
= get_teb64(params32
->teb
),
2040 .target
= params32
->target
,
2041 .offset
= (GLintptr
)ULongToPtr(params32
->offset
),
2042 .length
= (GLsizeiptr
)ULongToPtr(params32
->length
),
2043 .access
= params32
->access
,
2047 /* already mapped, we're being called again with a wow64 pointer */
2048 if (params32
->ret
) params
.ret
= (char *)get_buffer_pointer( params
.teb
, params
.target
);
2049 else if ((status
= ext_glMapBufferRange( ¶ms
))) return status
;
2051 status
= wow64_map_buffer( params
.teb
, 0, params
.target
, params
.ret
, params
.length
, params
.access
, ¶ms32
->ret
);
2052 if (!status
|| status
== STATUS_INVALID_ADDRESS
) return status
;
2054 unmap_buffer( params
.teb
, params
.target
);
2058 static NTSTATUS
wow64_gl_map_named_buffer( void *args
, NTSTATUS (*gl_map_named_buffer64
)(void *) )
2067 struct glMapNamedBuffer_params params
=
2069 .teb
= get_teb64(params32
->teb
),
2070 .buffer
= params32
->buffer
,
2071 .access
= params32
->access
,
2075 /* already mapped, we're being called again with a wow64 pointer */
2076 if (params32
->ret
) params
.ret
= get_named_buffer_pointer( params
.teb
, params
.buffer
);
2077 else if ((status
= gl_map_named_buffer64( ¶ms
))) return status
;
2079 status
= wow64_map_buffer( params
.teb
, params
.buffer
, 0, params
.ret
, 0,
2080 map_range_flags_from_map_flags( params
.access
), ¶ms32
->ret
);
2081 if (!status
|| status
== STATUS_INVALID_ADDRESS
) return status
;
2083 unmap_named_buffer( params
.teb
, params
.buffer
);
2087 NTSTATUS
wow64_ext_glMapNamedBuffer( void *args
)
2089 return wow64_gl_map_named_buffer( args
, ext_glMapNamedBuffer
);
2092 NTSTATUS
wow64_ext_glMapNamedBufferEXT( void *args
)
2094 return wow64_gl_map_named_buffer( args
, ext_glMapNamedBufferEXT
);
2097 static NTSTATUS
wow64_gl_map_named_buffer_range( void *args
, NTSTATUS (*gl_map_named_buffer_range64
)(void *) )
2108 struct glMapNamedBufferRange_params params
=
2110 .teb
= get_teb64(params32
->teb
),
2111 .buffer
= params32
->buffer
,
2112 .offset
= (GLintptr
)ULongToPtr(params32
->offset
),
2113 .length
= (GLsizeiptr
)ULongToPtr(params32
->length
),
2114 .access
= params32
->access
,
2118 /* already mapped, we're being called again with a wow64 pointer */
2119 if (params32
->ret
) params
.ret
= get_named_buffer_pointer( params
.teb
, params
.buffer
);
2120 else if ((status
= gl_map_named_buffer_range64( ¶ms
))) return status
;
2122 status
= wow64_map_buffer( params
.teb
, params
.buffer
, 0, params
.ret
, params
.length
, params
.access
, ¶ms32
->ret
);
2123 if (!status
|| status
== STATUS_INVALID_ADDRESS
) return status
;
2125 unmap_named_buffer( params
.teb
, params
.buffer
);
2129 NTSTATUS
wow64_ext_glMapNamedBufferRange( void *args
)
2131 return wow64_gl_map_named_buffer_range( args
, ext_glMapNamedBufferRange
);
2134 NTSTATUS
wow64_ext_glMapNamedBufferRangeEXT( void *args
)
2136 return wow64_gl_map_named_buffer_range( args
, ext_glMapNamedBufferRangeEXT
);
2139 static NTSTATUS
wow64_gl_unmap_buffer( void *args
, NTSTATUS (*gl_unmap_buffer64
)(void *) )
2148 struct glUnmapBuffer_params params
=
2150 .teb
= get_teb64(params32
->teb
),
2151 .target
= params32
->target
,
2156 if (!(ptr
= get_buffer_pointer( params
.teb
, params
.target
))) return STATUS_SUCCESS
;
2158 status
= wow64_unmap_buffer( ptr
, get_buffer_param( params
.teb
, params
.target
, GL_BUFFER_MAP_LENGTH
),
2159 get_buffer_param( params
.teb
, params
.target
, GL_BUFFER_ACCESS_FLAGS
) );
2160 gl_unmap_buffer64( ¶ms
);
2161 params32
->ret
= params
.ret
;
2166 NTSTATUS
wow64_ext_glUnmapBuffer( void *args
)
2168 return wow64_gl_unmap_buffer( args
, ext_glUnmapBuffer
);
2171 NTSTATUS
wow64_ext_glUnmapBufferARB( void *args
)
2173 return wow64_gl_unmap_buffer( args
, ext_glUnmapBufferARB
);
2176 static NTSTATUS
wow64_gl_unmap_named_buffer( void *args
, NTSTATUS (*gl_unmap_named_buffer64
)(void *) )
2185 struct glUnmapNamedBuffer_params params
=
2187 .teb
= get_teb64(params32
->teb
),
2188 .buffer
= params32
->buffer
,
2193 if (!(ptr
= get_named_buffer_pointer( params
.teb
, params
.buffer
))) return STATUS_SUCCESS
;
2195 status
= wow64_unmap_buffer( ptr
, get_named_buffer_param( params
.teb
, params
.buffer
, GL_BUFFER_MAP_LENGTH
),
2196 get_named_buffer_param( params
.teb
, params
.buffer
, GL_BUFFER_ACCESS_FLAGS
) );
2197 gl_unmap_named_buffer64( ¶ms
);
2198 params32
->ret
= params
.ret
;
2203 NTSTATUS
wow64_ext_glUnmapNamedBuffer( void *args
)
2205 return wow64_gl_unmap_named_buffer( args
, ext_glUnmapNamedBuffer
);
2208 NTSTATUS
wow64_ext_glUnmapNamedBufferEXT( void *args
)
2210 return wow64_gl_unmap_named_buffer( args
, ext_glUnmapNamedBufferEXT
);
2213 NTSTATUS
wow64_thread_attach( void *args
)
2215 return thread_attach( get_teb64( (ULONG_PTR
)args
));
2218 NTSTATUS
wow64_process_detach( void *args
)
2222 if ((status
= process_detach( NULL
))) return status
;
2224 free( wow64_strings
);
2225 wow64_strings
= NULL
;
2226 wow64_strings_count
= 0;
2228 return STATUS_SUCCESS
;