From: Zebediah Figura zfigura@codeweavers.com
GL_MAP_WRITE_BIT does not mean that the buffer will be filled, unless an INVALIDATE bit is explicitly set. The application is free to partially update the buffer, even if it does not read from it.
Thanks to Aida Jonikienė for doing most of the debugging here.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55045 --- dlls/opengl32/unix_wgl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index e58e5b5d9b5..92a77b78f18 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -1827,7 +1827,7 @@ static NTSTATUS wow64_map_buffer( TEB *teb, GLint buffer, GLenum target, void *p { if (*ret) /* wow64 pointer provided, map buffer to it */ { - if (access & GL_MAP_READ_BIT) + if (!(access & (GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT))) { TRACE( "Copying %#zx from buffer at %p to wow64 buffer %p\n", size, ptr, UlongToPtr(*ret) ); memcpy( UlongToPtr(*ret), ptr, size );
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/opengl32/unix_wgl.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 92a77b78f18..a03f8337fbf 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -1857,6 +1857,19 @@ static NTSTATUS wow64_map_buffer( TEB *teb, GLint buffer, GLenum target, void *p return STATUS_INVALID_ADDRESS; }
+static GLbitfield map_range_flags_from_map_flags( GLenum flags ) +{ + switch (flags) + { + case GL_READ_ONLY: return GL_MAP_READ_BIT; + case GL_WRITE_ONLY: return GL_MAP_WRITE_BIT; + case GL_READ_WRITE: return GL_MAP_READ_BIT | GL_MAP_WRITE_BIT; + default: + ERR( "invalid map flags %#x\n", flags ); + return GL_MAP_READ_BIT | GL_MAP_WRITE_BIT; + } +} + static NTSTATUS wow64_unmap_buffer( void *ptr, SIZE_T size, GLbitfield access ) { void *wow_ptr; @@ -1968,7 +1981,8 @@ static NTSTATUS wow64_gl_map_buffer( void *args, NTSTATUS (*gl_map_buffer64)(voi if (params32->ret) params.ret = get_buffer_pointer( params.teb, params.target ); else if ((status = gl_map_buffer64( ¶ms ))) return status;
- status = wow64_map_buffer( params.teb, 0, params.target, params.ret, 0, params.access, ¶ms32->ret ); + status = wow64_map_buffer( params.teb, 0, params.target, params.ret, 0, + map_range_flags_from_map_flags( params.access ), ¶ms32->ret ); if (!status || status == STATUS_INVALID_ADDRESS) return status;
unmap_buffer( params.teb, params.target ); @@ -2038,7 +2052,8 @@ static NTSTATUS wow64_gl_map_named_buffer( void *args, NTSTATUS (*gl_map_named_b if (params32->ret) params.ret = get_named_buffer_pointer( params.teb, params.buffer ); else if ((status = gl_map_named_buffer64( ¶ms ))) return status;
- status = wow64_map_buffer( params.teb, params.buffer, 0, params.ret, 0, params.access, ¶ms32->ret ); + status = wow64_map_buffer( params.teb, params.buffer, 0, params.ret, 0, + map_range_flags_from_map_flags( params.access ), ¶ms32->ret ); if (!status || status == STATUS_INVALID_ADDRESS) return status;
unmap_named_buffer( params.teb, params.buffer );
While this does fix missing graphics/graphics corruption issues in WineD3D applications, the performance will be severely reduced due to extra memcpy() calls (so you should probably print a warning in the Wine log) 🐸
While this does fix missing graphics/graphics corruption issues in WineD3D applications, the performance will be severely reduced due to extra memcpy() calls (so you should probably print a warning in the Wine log) :frog:
Maybe, although that was already the case; this just does memcpy in a few more cases. I suppose I can send another patch.