[PATCH 0/5] MR10784: opengl32: Test and fix the default framebuffer behavior.
Query functions are broken when front buffer rendering emulation is used. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10784
From: Rémi Bernon <rbernon@codeweavers.com> Shows that it is broken because of front buffer rendering emulation. --- dlls/opengl32/tests/opengl.c | 495 +++++++++++++++++++++++++++++++---- 1 file changed, 447 insertions(+), 48 deletions(-) diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index 6ba55448bcb..d542672b61e 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -57,6 +57,7 @@ static const char *debugstr_ok( const char *cond ) ok( v op (e), "%s " f "\n", debugstr_ok( #r ), v, ##__VA_ARGS__ ); \ } while (0) #define ok_u4( r, op, e ) ok_ex( r, op, e, UINT, "%u" ) +#define ok_x4( r, op, e ) ok_ex( r, op, e, UINT, "%#x" ) #define ok_ptr( r, op, e ) ok_ex( r, op, e, const void *, "%p" ) #define ok_ret( e, r ) ok_ex( r, ==, e, UINT_PTR, "%#Ix, error %ld", GetLastError() ) #define ok_nt( e, r ) ok_ex( r, ==, e, NTSTATUS, "%#lx" ) @@ -3411,67 +3412,465 @@ static void test_minimized(void) static void test_framebuffer(void) { - static const PIXELFORMATDESCRIPTOR pf_desc = + PIXELFORMATDESCRIPTOR pfd = { - sizeof(PIXELFORMATDESCRIPTOR), - 1, /* version */ - PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, - PFD_TYPE_RGBA, - 24, /* 24-bit color depth */ - 0, 0, 0, 0, 0, 0, /* color bits */ - 0, /* alpha buffer */ - 0, /* shift bit */ - 0, /* accumulation buffer */ - 0, 0, 0, 0, /* accum bits */ - 32, /* z-buffer */ - 0, /* stencil buffer */ - 0, /* auxiliary buffer */ - PFD_MAIN_PLANE, /* main layer */ - 0, /* reserved */ - 0, 0, 0 /* layer masks */ + .nSize = sizeof(PIXELFORMATDESCRIPTOR), + .nVersion = 1, + .dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + .iPixelType = PFD_TYPE_RGBA, + .cColorBits = 24, }; - int pixel_format; + + int format; + GLuint fbo, rbos[2], buffers[2]; + HWND hwnd, hwnd2; + HGLRC ctx, ctx2; + HDC hdc, hdc2; GLenum status; - HWND window; - HGLRC ctx; - BOOL ret; - HDC dc; + GLint value; + BOOL amd; + /* Test the default framebuffer status for a window that becomes visible after wglMakeCurrent() */ - window = CreateWindowA("static", "opengl32_test", WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0); - ok(!!window, "Failed to create window, last error %#lx.\n", GetLastError()); - dc = GetDC(window); - ok(!!dc, "Failed to get DC.\n"); - pixel_format = ChoosePixelFormat(dc, &pf_desc); - if (!pixel_format) - { - win_skip("Failed to find pixel format.\n"); - ReleaseDC(window, dc); - DestroyWindow(window); - return; - } + hwnd = CreateWindowW( L"static", NULL, WS_POPUP, 0, 0, 200, 200, NULL, NULL, NULL, NULL ); + ok_ptr( hwnd, !=, NULL ); + hdc = GetDC( hwnd ); + ok_ptr( hdc, !=, NULL ); + format = ChoosePixelFormat( hdc, &pfd ); + ok_u4( format, >, 0 ); + ok_ret( TRUE, SetPixelFormat( hdc, format, &pfd ) ); - ret = SetPixelFormat(dc, pixel_format, &pf_desc); - ok(ret, "Failed to set pixel format, last error %#lx.\n", GetLastError()); - ctx = wglCreateContext(dc); - ok(!!ctx, "Failed to create GL context, last error %#lx.\n", GetLastError()); - ret = wglMakeCurrent(dc, ctx); - ok(ret, "Failed to make context current, last error %#lx.\n", GetLastError()); + ctx = wglCreateContext( hdc ); + ok_ptr( ctx, !=, NULL ); + ok_ret( TRUE, wglMakeCurrent( hdc, ctx ) ); + ok_ret( GL_NO_ERROR, glGetError() ); + ReleaseDC( hwnd, hdc ); - ShowWindow(window, SW_SHOW); + ShowWindow( hwnd, SW_SHOW ); flush_events(); ext.glBindFramebuffer( GL_FRAMEBUFFER, 0 ); + ok_ret( GL_NO_ERROR, glGetError() ); + status = ext.glCheckFramebufferStatus( GL_FRAMEBUFFER ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( status, ==, GL_FRAMEBUFFER_COMPLETE ); + + ok_ret( TRUE, wglDeleteContext( ctx ) ); + DestroyWindow( hwnd ); + + + hwnd = CreateWindowW( L"static", NULL, WS_POPUP, 0, 0, 200, 200, NULL, NULL, NULL, NULL ); + ok_ptr( hwnd, !=, NULL ); + hdc = GetDC( hwnd ); + ok_ptr( hdc, !=, NULL ); + format = ChoosePixelFormat( hdc, &pfd ); + ok_u4( format, >, 0 ); + ok_ret( TRUE, SetPixelFormat( hdc, format, &pfd ) ); + + ctx = wglCreateContext( hdc ); + ok_ptr( ctx, !=, NULL ); + ok_ret( TRUE, wglMakeCurrent( hdc, ctx ) ); + ReleaseDC( hwnd, hdc ); + + amd = strstr( (const char*)glGetString(GL_VENDOR), "AMD" ) || + strstr( (const char*)glGetString(GL_VENDOR), "ATI" ); status = ext.glCheckFramebufferStatus( GL_FRAMEBUFFER ); - ok(status == GL_FRAMEBUFFER_COMPLETE, "Expected %#x, got %#x.\n", GL_FRAMEBUFFER_COMPLETE, status); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( status, ==, GL_FRAMEBUFFER_COMPLETE ); + + /* only glGetFramebufferParameterivEXT allows querying draw/read buffers */ + ext.glGetFramebufferParameteriv( GL_FRAMEBUFFER, GL_DRAW_BUFFER, &value ); + ok_ret( GL_INVALID_ENUM, glGetError() ); + ext.glGetNamedFramebufferParameteriv( 0, GL_DRAW_BUFFER, &value ); + ok_ret( GL_INVALID_ENUM, glGetError() ); + ext.glGetNamedFramebufferParameterivEXT( 0, GL_DRAW_BUFFER, &value ); + ok_ret( GL_INVALID_ENUM, glGetError() ); + ext.glGetFramebufferParameterivEXT( 0, GL_DRAW_BUFFER, &value ); + if (broken( amd )) ok_ret( GL_INVALID_ENUM, glGetError() ); + else ok_x4( value, ==, GL_BACK ); + ext.glGetNamedFramebufferParameterivEXT( 0, GL_READ_BUFFER, &value ); + ok_ret( GL_INVALID_ENUM, glGetError() ); + ext.glGetFramebufferParameterivEXT( 0, GL_READ_BUFFER, &value ); + if (broken( amd )) ok_ret( GL_INVALID_ENUM, glGetError() ); + else ok_x4( value, ==, GL_BACK ); + ok_ret( GL_NO_ERROR, glGetError() ); - ret = wglMakeCurrent(NULL, NULL); - ok(ret, "Failed to clear current context, last error %#lx.\n", GetLastError()); - ret = wglDeleteContext(ctx); - ok(ret, "Failed to delete GL context, last error %#lx.\n", GetLastError()); - ReleaseDC(window, dc); - DestroyWindow(window); + ext.glGetFramebufferParameteriv( GL_FRAMEBUFFER, GL_DOUBLEBUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_TRUE ); + ext.glGetFramebufferParameteriv( GL_FRAMEBUFFER, GL_STEREO, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_FALSE ); + + ShowWindow( hwnd, SW_SHOW ); + flush_events(); + + status = ext.glCheckFramebufferStatus( GL_FRAMEBUFFER ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( status, ==, GL_FRAMEBUFFER_COMPLETE ); + ext.glGetFramebufferParameterivEXT( 0, GL_DRAW_BUFFER, &value ); + if (broken( amd )) ok_ret( GL_INVALID_ENUM, glGetError() ); + else ok_x4( value, ==, GL_BACK ); + ext.glGetFramebufferParameterivEXT( 0, GL_READ_BUFFER, &value ); + if (broken( amd )) ok_ret( GL_INVALID_ENUM, glGetError() ); + else ok_x4( value, ==, GL_BACK ); + ext.glGetFramebufferParameteriv( GL_FRAMEBUFFER, GL_DOUBLEBUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_TRUE ); + ext.glGetFramebufferParameteriv( GL_FRAMEBUFFER, GL_STEREO, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_FALSE ); + + + ext.glCreateFramebuffers( 1, &fbo ); + ok_ret( GL_NO_ERROR, glGetError() ); + ext.glBindFramebuffer( GL_FRAMEBUFFER, fbo ); + ok_ret( GL_NO_ERROR, glGetError() ); + status = ext.glCheckFramebufferStatus( GL_FRAMEBUFFER ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( status, ==, GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT ); + ext.glGetFramebufferParameterivEXT( fbo, GL_DRAW_BUFFER, &value ); + if (broken( amd )) ok_ret( GL_INVALID_ENUM, glGetError() ); + else ok_x4( value, ==, GL_COLOR_ATTACHMENT0 ); + ext.glGetFramebufferParameterivEXT( fbo, GL_READ_BUFFER, &value ); + if (broken( amd )) ok_ret( GL_INVALID_ENUM, glGetError() ); + else ok_x4( value, ==, GL_COLOR_ATTACHMENT0 ); + ext.glGetFramebufferParameteriv( GL_FRAMEBUFFER, GL_DOUBLEBUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, broken( amd ) ? GL_TRUE : GL_FALSE ); + ext.glGetFramebufferParameteriv( GL_FRAMEBUFFER, GL_STEREO, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_FALSE ); + + + ext.glCreateRenderbuffers( 2, rbos ); + ok_ret( GL_NO_ERROR, glGetError() ); + ext.glBindRenderbuffer( GL_RENDERBUFFER, rbos[0] ); + ok_ret( GL_NO_ERROR, glGetError() ); + ext.glRenderbufferStorage( GL_RENDERBUFFER, GL_RGBA, 1, 1 ); + ok_ret( GL_NO_ERROR, glGetError() ); + ext.glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbos[0] ); + ok_ret( GL_NO_ERROR, glGetError() ); + ext.glBindRenderbuffer( GL_RENDERBUFFER, rbos[1] ); + ok_ret( GL_NO_ERROR, glGetError() ); + ext.glRenderbufferStorage( GL_RENDERBUFFER, GL_RGBA, 1, 1 ); + ok_ret( GL_NO_ERROR, glGetError() ); + ext.glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, rbos[1] ); + ok_ret( GL_NO_ERROR, glGetError() ); + + status = ext.glCheckFramebufferStatus( GL_FRAMEBUFFER ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( status, ==, GL_FRAMEBUFFER_COMPLETE ); + ext.glGetFramebufferParameterivEXT( fbo, GL_DRAW_BUFFER, &value ); + if (broken( amd )) ok_ret( GL_INVALID_ENUM, glGetError() ); + else ok_x4( value, ==, GL_COLOR_ATTACHMENT0 ); + ext.glGetFramebufferParameterivEXT( fbo, GL_READ_BUFFER, &value ); + if (broken( amd )) ok_ret( GL_INVALID_ENUM, glGetError() ); + else ok_x4( value, ==, GL_COLOR_ATTACHMENT0 ); + ext.glGetFramebufferParameteriv( GL_FRAMEBUFFER, GL_DOUBLEBUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, broken( amd ) ? GL_TRUE : GL_FALSE ); + ext.glGetFramebufferParameteriv( GL_FRAMEBUFFER, GL_STEREO, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_FALSE ); + + + ext.glBindFramebuffer( GL_READ_FRAMEBUFFER, fbo ); + ok_ret( GL_NO_ERROR, glGetError() ); + ext.glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 ); + ok_ret( GL_NO_ERROR, glGetError() ); + glGetIntegerv( GL_DRAW_FRAMEBUFFER_BINDING, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_u4( value, ==, 0 ); + glGetIntegerv( GL_READ_FRAMEBUFFER_BINDING, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_u4( value, ==, fbo ); + + glGetIntegerv( GL_DRAW_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_BACK ); + glGetIntegerv( GL_READ_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_COLOR_ATTACHMENT0 ); + ext.glGetFramebufferParameteriv( GL_FRAMEBUFFER, GL_DOUBLEBUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_TRUE ); + ext.glGetFramebufferParameteriv( GL_FRAMEBUFFER, GL_STEREO, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_FALSE ); + ext.glGetFramebufferParameteriv( GL_READ_FRAMEBUFFER, GL_DOUBLEBUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, broken( amd ) ? GL_TRUE : GL_FALSE ); + ext.glGetFramebufferParameteriv( GL_READ_FRAMEBUFFER, GL_STEREO, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_FALSE ); + + + glDrawBuffer( GL_FRONT_AND_BACK ); + ok_ret( GL_NO_ERROR, glGetError() ); + glReadBuffer( GL_FRONT_LEFT ); + ok_ret( GL_INVALID_OPERATION, glGetError() ); + glReadBuffer( GL_COLOR_ATTACHMENT1 ); + ok_ret( GL_NO_ERROR, glGetError() ); + glGetIntegerv( GL_DRAW_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_x4( value, ==, GL_FRONT_AND_BACK ); + glGetIntegerv( GL_DRAW_BUFFER1, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_NONE ); + glGetIntegerv( GL_READ_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_COLOR_ATTACHMENT1 ); + + ext.glGetFramebufferParameterivEXT( 0, GL_DRAW_BUFFER, &value ); + if (broken( amd )) ok_ret( GL_INVALID_ENUM, glGetError() ); + else todo_wine ok_x4( value, ==, GL_FRONT_AND_BACK ); + ext.glGetFramebufferParameterivEXT( 0, GL_READ_BUFFER, &value ); + if (broken( amd )) ok_ret( GL_INVALID_ENUM, glGetError() ); + else ok_x4( value, ==, GL_BACK ); + ext.glGetFramebufferParameterivEXT( fbo, GL_DRAW_BUFFER, &value ); + if (broken( amd )) ok_ret( GL_INVALID_ENUM, glGetError() ); + else ok_x4( value, ==, GL_COLOR_ATTACHMENT0 ); + ext.glGetFramebufferParameterivEXT( fbo, GL_READ_BUFFER, &value ); + if (broken( amd )) ok_ret( GL_INVALID_ENUM, glGetError() ); + else ok_x4( value, ==, GL_COLOR_ATTACHMENT1 ); + ok_ret( GL_NO_ERROR, glGetError() ); + + + hdc = GetDC( hwnd ); + ok_ptr( hdc, !=, NULL ); + ctx2 = ext.wglCreateContextAttribsARB( hdc, ctx, NULL ); + ok_ptr( ctx2, !=, NULL ); + + hwnd2 = CreateWindowW( L"static", NULL, WS_POPUP, 0, 0, 200, 200, NULL, NULL, NULL, NULL ); + ok_ptr( hwnd2, !=, NULL ); + hdc2 = GetDC( hwnd2 ); + ok_ptr( hdc2, !=, NULL ); + pfd.dwFlags &= ~PFD_DOUBLEBUFFER; + format = ChoosePixelFormat( hdc2, &pfd ); + ok_u4( format, >, 0 ); + ok_ret( TRUE, SetPixelFormat( hdc2, format, &pfd ) ); + + if (!broken( amd )) /* AMD allows to mix DCs with different pixel formats */ + { + SetLastError( 0xdeadbeef ); + todo_wine ok_ret( FALSE, ext.wglMakeContextCurrentARB( hdc, hdc2, ctx2 ) ); + todo_wine ok_ret( ERROR_INVALID_PIXEL_FORMAT, LOWORD( GetLastError() ) ); + ok_ret( TRUE, wglDeleteContext( ctx2 ) ); + ctx2 = ext.wglCreateContextAttribsARB( hdc2, ctx, NULL ); + ok_ptr( ctx2, !=, NULL ); + ok_ret( FALSE, ext.wglMakeContextCurrentARB( hdc, hdc2, ctx2 ) ); + ok_ret( ERROR_INVALID_PIXEL_FORMAT, LOWORD( GetLastError() ) ); + } + + ok_ret( TRUE, ext.wglMakeContextCurrentARB( hdc2, hdc2, ctx2 ) ); + + glGetIntegerv( GL_DRAW_FRAMEBUFFER_BINDING, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_u4( value, ==, 0 ); + glGetIntegerv( GL_READ_FRAMEBUFFER_BINDING, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_u4( value, ==, 0 ); + + ext.glGetFramebufferParameteriv( GL_READ_FRAMEBUFFER, GL_DOUBLEBUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_x4( value, ==, GL_FALSE ); + ext.glGetFramebufferParameteriv( GL_READ_FRAMEBUFFER, GL_STEREO, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_FALSE ); + glGetIntegerv( GL_DRAW_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_x4( value, ==, GL_FRONT ); + glGetIntegerv( GL_READ_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_x4( value, ==, GL_FRONT ); + + glDrawBuffer( GL_FRONT_AND_BACK ); + ok_ret( GL_NO_ERROR, glGetError() ); + glDrawBuffer( GL_RIGHT ); + ok_ret( GL_INVALID_OPERATION, glGetError() ); + glGetIntegerv( GL_DRAW_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_x4( value, ==, GL_FRONT_AND_BACK ); + glGetIntegerv( GL_DRAW_BUFFER1, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_NONE ); + glGetIntegerv( GL_READ_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_x4( value, ==, GL_FRONT ); + buffers[0] = GL_FRONT_LEFT; + buffers[1] = GL_FRONT_LEFT; + ext.glDrawBuffers( 2, buffers ); + ok_ret( GL_INVALID_OPERATION, glGetError() ); + buffers[0] = GL_FRONT_LEFT; + buffers[1] = GL_BACK_LEFT; + ext.glDrawBuffers( 2, buffers ); + ok_ret( GL_INVALID_OPERATION, glGetError() ); + buffers[0] = GL_FRONT_AND_BACK; + buffers[1] = GL_FRONT_LEFT; + ext.glDrawBuffers( 2, buffers ); + todo_wine ok_ret( GL_INVALID_ENUM, glGetError() ); + glGetIntegerv( GL_DRAW_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_x4( value, ==, GL_FRONT_AND_BACK ); + glGetIntegerv( GL_DRAW_BUFFER1, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_NONE ); + glGetIntegerv( GL_READ_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_x4( value, ==, GL_FRONT ); + + glReadBuffer( GL_NONE ); + ok_ret( GL_NO_ERROR, glGetError() ); + glGetIntegerv( GL_DRAW_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_x4( value, ==, GL_FRONT_AND_BACK ); + glGetIntegerv( GL_DRAW_BUFFER1, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_NONE ); + glGetIntegerv( GL_READ_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_NONE ); + + glDrawBuffer( GL_NONE ); + ok_ret( GL_NO_ERROR, glGetError() ); + glGetIntegerv( GL_DRAW_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_NONE ); + glGetIntegerv( GL_DRAW_BUFFER1, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_NONE ); + glGetIntegerv( GL_READ_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_NONE ); + + ext.glGetFramebufferParameterivEXT( fbo, GL_DRAW_BUFFER, &value ); + if (broken( amd )) ok_ret( GL_INVALID_ENUM, glGetError() ); + else ok_x4( value, ==, GL_COLOR_ATTACHMENT0 ); + ext.glGetFramebufferParameterivEXT( fbo, GL_READ_BUFFER, &value ); + if (broken( amd )) ok_ret( GL_INVALID_ENUM, glGetError() ); + else ok_x4( value, ==, GL_COLOR_ATTACHMENT1 ); + ok_ret( GL_NO_ERROR, glGetError() ); + + ok_ret( TRUE, wglDeleteContext( ctx2 ) ); + ReleaseDC( hwnd2, hdc2 ); + DestroyWindow( hwnd2 ); + + + hwnd2 = CreateWindowW( L"static", NULL, WS_POPUP, 0, 0, 200, 200, NULL, NULL, NULL, NULL ); + ok_ptr( hwnd2, !=, NULL ); + hdc2 = GetDC( hwnd2 ); + ok_ptr( hdc2, !=, NULL ); + pfd.dwFlags |= PFD_DOUBLEBUFFER; + format = ChoosePixelFormat( hdc2, &pfd ); + ok_u4( format, >, 0 ); + ok_ret( TRUE, SetPixelFormat( hdc2, format, &pfd ) ); + + ok_ret( TRUE, ext.wglMakeContextCurrentARB( hdc, hdc2, ctx ) ); + + glGetIntegerv( GL_DRAW_FRAMEBUFFER_BINDING, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_u4( value, ==, 0 ); + glGetIntegerv( GL_READ_FRAMEBUFFER_BINDING, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_u4( value, ==, fbo ); + + status = ext.glCheckFramebufferStatus( GL_FRAMEBUFFER ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( status, ==, GL_FRAMEBUFFER_COMPLETE ); + glGetIntegerv( GL_DRAW_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_x4( value, ==, GL_FRONT_AND_BACK ); + glGetIntegerv( GL_READ_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_COLOR_ATTACHMENT1 ); + + status = ext.glCheckFramebufferStatus( GL_READ_FRAMEBUFFER ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( status, ==, GL_FRAMEBUFFER_COMPLETE ); + ext.glGetFramebufferParameterivEXT( fbo, GL_DRAW_BUFFER, &value ); + if (broken( amd )) ok_ret( GL_INVALID_ENUM, glGetError() ); + else ok_x4( value, ==, GL_COLOR_ATTACHMENT0 ); + ext.glGetFramebufferParameterivEXT( fbo, GL_READ_BUFFER, &value ); + if (broken( amd )) ok_ret( GL_INVALID_ENUM, glGetError() ); + else ok_x4( value, ==, GL_COLOR_ATTACHMENT1 ); + ok_ret( GL_NO_ERROR, glGetError() ); + + ok_ret( TRUE, ext.wglMakeContextCurrentARB( hdc2, hdc, ctx ) ); + ReleaseDC( hwnd, hdc ); + ReleaseDC( hwnd2, hdc2 ); + + glGetIntegerv( GL_DRAW_FRAMEBUFFER_BINDING, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_u4( value, ==, 0 ); + glGetIntegerv( GL_READ_FRAMEBUFFER_BINDING, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_u4( value, ==, fbo ); + + glGetIntegerv( GL_DRAW_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_x4( value, ==, GL_FRONT_AND_BACK ); + glGetIntegerv( GL_READ_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_COLOR_ATTACHMENT1 ); + + buffers[0] = GL_FRONT_LEFT; + buffers[1] = GL_BACK_LEFT; + ext.glDrawBuffers( 2, buffers ); + todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + glGetIntegerv( GL_DRAW_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_x4( value, ==, GL_FRONT_LEFT ); + glGetIntegerv( GL_DRAW_BUFFER1, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_x4( value, ==, GL_BACK_LEFT ); + glGetIntegerv( GL_READ_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_COLOR_ATTACHMENT1 ); + + glDrawBuffer( GL_FRONT_AND_BACK ); + ok_ret( GL_NO_ERROR, glGetError() ); + glGetIntegerv( GL_DRAW_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_x4( value, ==, GL_FRONT_AND_BACK ); + glGetIntegerv( GL_DRAW_BUFFER1, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_NONE ); + glGetIntegerv( GL_READ_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_COLOR_ATTACHMENT1 ); + + buffers[0] = GL_FRONT_LEFT; + buffers[1] = GL_BACK_LEFT; + ext.glDrawBuffers( 2, buffers ); + todo_wine ok_ret( GL_NO_ERROR, glGetError() ); + glGetIntegerv( GL_DRAW_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_x4( value, ==, GL_FRONT_LEFT ); + glGetIntegerv( GL_DRAW_BUFFER1, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + todo_wine ok_x4( value, ==, GL_BACK_LEFT ); + glGetIntegerv( GL_READ_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_COLOR_ATTACHMENT1 ); + + glDrawBuffer( GL_NONE ); + ok_ret( GL_NO_ERROR, glGetError() ); + glGetIntegerv( GL_DRAW_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_NONE ); + glGetIntegerv( GL_DRAW_BUFFER1, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_NONE ); + glGetIntegerv( GL_READ_BUFFER, &value ); + ok_ret( GL_NO_ERROR, glGetError() ); + ok_x4( value, ==, GL_COLOR_ATTACHMENT1 ); + + + ok_ret( TRUE, wglDeleteContext( ctx ) ); + DestroyWindow( hwnd ); + DestroyWindow( hwnd2 ); } static DWORD CALLBACK test_window_dc_thread( void *arg ) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10784
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/win32u/opengl.c | 44 ++++++++++++++++++++++++----------- dlls/winewayland.drv/opengl.c | 9 +++---- dlls/winex11.drv/opengl.c | 9 +++---- include/wine/opengl_driver.h | 5 ++++ 4 files changed, 45 insertions(+), 22 deletions(-) diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 0815f4378e8..6c1040554b9 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -111,7 +111,23 @@ void *opengl_drawable_create( UINT size, const struct opengl_drawable_funcs *fun drawable->doublebuffer = !!(pixel_formats[format - 1].pfd.dwFlags & PFD_DOUBLEBUFFER); drawable->stereo = !!(pixel_formats[format - 1].pfd.dwFlags & PFD_STEREO); if ((drawable->client = client)) client_surface_add_ref( client ); - for (UINT i = 0; i < ARRAY_SIZE(drawable->buffer_map); i++) drawable->buffer_map[i] = GL_FRONT_LEFT + i; + + opengl_drawable_map_buffer( drawable, GL_FRONT_LEFT, GL_FRONT_LEFT ); + opengl_drawable_map_buffer( drawable, GL_FRONT, GL_FRONT ); + opengl_drawable_map_buffer( drawable, GL_LEFT, GL_LEFT ); + opengl_drawable_map_buffer( drawable, GL_FRONT_AND_BACK, GL_FRONT_AND_BACK ); + + if (drawable->doublebuffer) + { + opengl_drawable_map_buffer( drawable, GL_BACK_LEFT, GL_BACK_LEFT ); + opengl_drawable_map_buffer( drawable, GL_BACK, GL_BACK ); + } + if (drawable->stereo) + { + opengl_drawable_map_buffer( drawable, GL_FRONT_RIGHT, GL_FRONT_RIGHT ); + opengl_drawable_map_buffer( drawable, GL_RIGHT, GL_RIGHT ); + if (drawable->doublebuffer) opengl_drawable_map_buffer( drawable, GL_BACK_RIGHT, GL_BACK_RIGHT ); + } TRACE( "created %s\n", debugstr_opengl_drawable( drawable ) ); return drawable; @@ -404,23 +420,23 @@ static struct opengl_drawable *framebuffer_surface_create( int format, struct cl struct framebuffer_surface *surface; if (!(surface = opengl_drawable_create( sizeof(*surface), &framebuffer_surface_funcs, format, client ))) return NULL; - surface->base.buffer_map[0] = GL_COLOR_ATTACHMENT0; - surface->base.buffer_map[2] = surface->base.doublebuffer ? GL_COLOR_ATTACHMENT1 : GL_NONE; - if (surface->base.stereo) + opengl_drawable_map_buffer( &surface->base, GL_FRONT_LEFT, GL_COLOR_ATTACHMENT0 ); + opengl_drawable_map_buffer( &surface->base, GL_FRONT, GL_COLOR_ATTACHMENT0 ); /* only front left */ + opengl_drawable_map_buffer( &surface->base, GL_LEFT, GL_COLOR_ATTACHMENT0 ); /* only front left */ + opengl_drawable_map_buffer( &surface->base, GL_FRONT_AND_BACK, GL_COLOR_ATTACHMENT0 ); /* only front left */ + + if (surface->base.doublebuffer) { - surface->base.buffer_map[1] = surface->base.doublebuffer ? GL_COLOR_ATTACHMENT2 : GL_COLOR_ATTACHMENT1; - surface->base.buffer_map[3] = surface->base.doublebuffer ? GL_COLOR_ATTACHMENT3 : GL_NONE; + opengl_drawable_map_buffer( &surface->base, GL_BACK_LEFT, GL_COLOR_ATTACHMENT1 ); + opengl_drawable_map_buffer( &surface->base, GL_BACK, GL_COLOR_ATTACHMENT1 ); /* only back left */ } - else + if (surface->base.stereo) { - surface->base.buffer_map[1] = GL_NONE; - surface->base.buffer_map[3] = GL_NONE; + GLenum attachment = surface->base.doublebuffer ? GL_COLOR_ATTACHMENT2 : GL_COLOR_ATTACHMENT1; + opengl_drawable_map_buffer( &surface->base, GL_FRONT_RIGHT, attachment ); + opengl_drawable_map_buffer( &surface->base, GL_RIGHT, attachment ); /* only front right */ + if (surface->base.doublebuffer) opengl_drawable_map_buffer( &surface->base, GL_BACK_RIGHT, GL_COLOR_ATTACHMENT3 ); } - surface->base.buffer_map[GL_FRONT - GL_FRONT_LEFT] = surface->base.buffer_map[0]; /* only front left */ - surface->base.buffer_map[GL_BACK - GL_FRONT_LEFT] = surface->base.buffer_map[2]; /* only back left */ - surface->base.buffer_map[GL_LEFT - GL_FRONT_LEFT] = surface->base.buffer_map[0]; /* only front left */ - surface->base.buffer_map[GL_RIGHT - GL_FRONT_LEFT] = surface->base.buffer_map[1]; /* only front right */ - surface->base.buffer_map[GL_FRONT_AND_BACK - GL_FRONT_LEFT] = surface->base.buffer_map[0]; /* only front left */ return &surface->base; } diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index 1486e411734..66457e1aea5 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -110,10 +110,11 @@ static BOOL wayland_opengl_surface_create(HWND hwnd, int format, struct opengl_d gl = opengl_drawable_create(sizeof(*gl), &wayland_drawable_funcs, format, &client->client); client_surface_release(&client->client); if (!gl) return FALSE; - gl->base.buffer_map[0] = GL_BACK_LEFT; - gl->base.buffer_map[1] = GL_BACK_RIGHT; - gl->base.buffer_map[GL_FRONT - GL_FRONT_LEFT] = GL_BACK; - gl->base.buffer_map[GL_FRONT_AND_BACK - GL_FRONT_LEFT] = GL_BACK; + + opengl_drawable_map_buffer(&gl->base, GL_FRONT_LEFT, GL_BACK_LEFT); + opengl_drawable_map_buffer(&gl->base, GL_FRONT, GL_BACK); + opengl_drawable_map_buffer(&gl->base, GL_FRONT_AND_BACK, GL_BACK); + if (gl->base.stereo) opengl_drawable_map_buffer(&gl->base, GL_FRONT_RIGHT, GL_BACK_RIGHT); if (!(gl->wl_egl_window = wl_egl_window_create(client->wl_surface, rect.right, rect.bottom))) goto err; if (!(gl->base.surface = funcs->p_eglCreateWindowSurface(egl->display, config, gl->wl_egl_window, attribs))) goto err; diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 7ebc2c43753..56c22ab7ee7 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -531,10 +531,11 @@ static BOOL x11drv_egl_surface_create( HWND hwnd, int format, struct opengl_draw gl = opengl_drawable_create( sizeof(*gl), &x11drv_egl_surface_funcs, format, client ); client_surface_release( client ); if (!gl) return FALSE; - gl->base.buffer_map[0] = GL_BACK_LEFT; - gl->base.buffer_map[1] = GL_BACK_RIGHT; - gl->base.buffer_map[GL_FRONT - GL_FRONT_LEFT] = GL_BACK; - gl->base.buffer_map[GL_FRONT_AND_BACK - GL_FRONT_LEFT] = GL_BACK; + + opengl_drawable_map_buffer( &gl->base, GL_FRONT_LEFT, GL_BACK_LEFT ); + opengl_drawable_map_buffer( &gl->base, GL_FRONT, GL_BACK ); + opengl_drawable_map_buffer( &gl->base, GL_FRONT_AND_BACK, GL_BACK ); + if (gl->base.stereo) opengl_drawable_map_buffer( &gl->base, GL_FRONT_RIGHT, GL_BACK_RIGHT ); if (!(gl->base.surface = funcs->p_eglCreateWindowSurface( egl->display, egl_config_for_format( format ), (void *)window, NULL ))) diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 777a82c338a..8249a6a5e82 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -223,6 +223,11 @@ static inline const char *debugstr_opengl_drawable( struct opengl_drawable *draw return wine_dbg_sprintf( "%s/%p (format %u)", debugstr_client_surface( drawable->client ), drawable, drawable->format ); } +static inline void opengl_drawable_map_buffer( struct opengl_drawable *drawable, GLenum buffer, GLenum set ) +{ + drawable->buffer_map[buffer - GL_FRONT_LEFT] = set; +} + W32KAPI void *opengl_drawable_create( UINT size, const struct opengl_drawable_funcs *funcs, int format, struct client_surface *client ); W32KAPI void opengl_drawable_add_ref( struct opengl_drawable *drawable ); W32KAPI void opengl_drawable_release( struct opengl_drawable *drawable ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10784
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/opengl32/unix_wgl.c | 76 ++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 31 deletions(-) diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index e5386290538..c28c46f6cbf 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -1208,21 +1208,42 @@ static GLenum drawable_buffer_from_buffer( struct opengl_drawable *drawable, GLe return drawable->buffer_map[buffer - GL_FRONT_LEFT]; } +enum buffer_mask +{ + MASK_NONE = 0, + MASK_FRONT_LEFT = 1, + MASK_FRONT_RIGHT = 2, + MASK_BACK_LEFT = 4, + MASK_BACK_RIGHT = 8, + MASK_BACK = MASK_BACK_LEFT | MASK_BACK_RIGHT, + MASK_FRONT = MASK_FRONT_LEFT | MASK_FRONT_RIGHT, + MASK_LEFT = MASK_FRONT_LEFT | MASK_BACK_LEFT, + MASK_RIGHT = MASK_FRONT_RIGHT | MASK_BACK_RIGHT, + MASK_ALL = MASK_FRONT | MASK_BACK, +}; + +static enum buffer_mask buffer_mask_from_enum( GLenum buffer ) +{ + switch (buffer) + { + case GL_BACK: return MASK_BACK; + case GL_BACK_LEFT: return MASK_BACK_LEFT; + case GL_BACK_RIGHT: return MASK_BACK_LEFT; + case GL_FRONT: return MASK_FRONT; + case GL_FRONT_LEFT: return MASK_FRONT_LEFT; + case GL_FRONT_RIGHT: return MASK_FRONT_RIGHT; + case GL_LEFT: return MASK_LEFT; + case GL_RIGHT: return MASK_RIGHT; + case GL_FRONT_AND_BACK: return MASK_ALL; + default: return MASK_NONE; + } +} + static BOOL context_draws_back( struct context *ctx ) { for (int i = 0; i < ARRAY_SIZE(ctx->color_buffer.draw_buffers); i++) - { - switch (ctx->color_buffer.draw_buffers[i]) - { - case GL_LEFT: - case GL_RIGHT: - case GL_BACK: - case GL_FRONT_AND_BACK: - case GL_BACK_LEFT: - case GL_BACK_RIGHT: + if (buffer_mask_from_enum( ctx->color_buffer.draw_buffers[i] ) & MASK_BACK) return TRUE; - } - } return FALSE; } @@ -1230,19 +1251,8 @@ static BOOL context_draws_back( struct context *ctx ) static BOOL context_draws_front( struct context *ctx ) { for (int i = 0; i < ARRAY_SIZE(ctx->color_buffer.draw_buffers); i++) - { - switch (ctx->color_buffer.draw_buffers[i]) - { - case GL_LEFT: - case GL_RIGHT: - case GL_FRONT: - case GL_FRONT_AND_BACK: - case GL_FRONT_LEFT: - case GL_FRONT_RIGHT: + if (buffer_mask_from_enum( ctx->color_buffer.draw_buffers[i] ) & MASK_FRONT) return TRUE; - } - } - return FALSE; } @@ -1602,18 +1612,22 @@ void resolve_default_fbo( TEB *teb, BOOL read ) static GLenum *set_default_fbo_draw_buffers( struct context *ctx, struct opengl_drawable *draw, GLsizei count, const GLenum *src, GLenum *dst ) { - memset( ctx->color_buffer.draw_buffers, 0, sizeof(ctx->color_buffer.draw_buffers) ); + UINT used[4] = {0}; + for (GLsizei i = 0; i < count; i++) dst[i] = GL_BACK_LEFT; /* some invalid combination */ for (GLsizei i = 0; i < count; i++) { - dst[i] = drawable_buffer_from_buffer( draw, src[i] ); - if (src[i] && !dst[i]) - { - WARN( "Invalid draw buffer #%d %#x for context %p\n", i, src[i], ctx ); - dst[i] = src[i]; - continue; - } + if ((buffer_mask_from_enum( src[i] ) & MASK_FRONT_LEFT) && used[0]++) return dst; + if ((buffer_mask_from_enum( src[i] ) & MASK_FRONT_RIGHT) && used[1]++) return dst; + if ((buffer_mask_from_enum( src[i] ) & MASK_BACK_LEFT) && used[2]++) return dst; + if ((buffer_mask_from_enum( src[i] ) & MASK_BACK_RIGHT) && used[3]++) return dst; + if (src[i] && !drawable_buffer_from_buffer( draw, src[i] )) return dst; + } + memset( ctx->color_buffer.draw_buffers, 0, sizeof(ctx->color_buffer.draw_buffers) ); + for (GLsizei i = 0; i < count; i++) + { + dst[i] = drawable_buffer_from_buffer( draw, src[i] ); if (i >= MAX_DRAW_BUFFERS) FIXME( "Needs %u draw buffers\n", i ); else ctx->color_buffer.draw_buffers[i] = src[i]; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10784
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/opengl32/unix_wgl.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index c28c46f6cbf..26741a40773 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -744,14 +744,12 @@ static BOOL get_default_fbo_integer( struct context *ctx, struct opengl_drawable { if (pname == GL_READ_BUFFER && !ctx->read_fbo && read->read_fbo) { - if (ctx->pixel_mode.read_buffer) *data = ctx->pixel_mode.read_buffer; - else *data = read->doublebuffer ? GL_BACK : GL_FRONT; + *data = ctx->pixel_mode.read_buffer; return TRUE; } if ((pname == GL_DRAW_BUFFER || pname == GL_DRAW_BUFFER0) && !ctx->draw_fbo && draw->draw_fbo) { - if (ctx->color_buffer.draw_buffers[0]) *data = ctx->color_buffer.draw_buffers[0]; - else *data = draw->doublebuffer ? GL_BACK : GL_FRONT; + *data = ctx->color_buffer.draw_buffers[0]; return TRUE; } if (pname >= GL_DRAW_BUFFER1 && pname <= GL_DRAW_BUFFER15 && !ctx->draw_fbo && draw->draw_fbo) @@ -1141,6 +1139,9 @@ static void make_context_current( TEB *teb, const struct opengl_funcs *funcs, HD client->extension_count = count; if (TRACE_ON(opengl)) for (i = 0; i < count; i++) TRACE( "++ %s\n", all_extensions[client->extension_array[i]].name ); + + ctx->color_buffer.draw_buffers[0] = ctx->base.draw->doublebuffer ? GL_BACK : GL_FRONT; + ctx->pixel_mode.read_buffer = ctx->base.draw->doublebuffer ? GL_BACK : GL_FRONT; } BOOL wrap_wglMakeCurrent( TEB *teb, HDC hdc, HGLRC client_context ) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10784
From: Rémi Bernon <rbernon@codeweavers.com> Not just when using framebuffer surfaces, making sure it works as intended and catch more issues if it does not. --- dlls/opengl32/tests/opengl.c | 32 ++++++++++++++++---------------- dlls/opengl32/unix_wgl.c | 17 +++++++++-------- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index d542672b61e..0bfb394c357 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -3615,7 +3615,7 @@ static void test_framebuffer(void) ok_ret( GL_NO_ERROR, glGetError() ); glGetIntegerv( GL_DRAW_BUFFER, &value ); ok_ret( GL_NO_ERROR, glGetError() ); - todo_wine ok_x4( value, ==, GL_FRONT_AND_BACK ); + ok_x4( value, ==, GL_FRONT_AND_BACK ); glGetIntegerv( GL_DRAW_BUFFER1, &value ); ok_ret( GL_NO_ERROR, glGetError() ); ok_x4( value, ==, GL_NONE ); @@ -3625,7 +3625,7 @@ static void test_framebuffer(void) ext.glGetFramebufferParameterivEXT( 0, GL_DRAW_BUFFER, &value ); if (broken( amd )) ok_ret( GL_INVALID_ENUM, glGetError() ); - else todo_wine ok_x4( value, ==, GL_FRONT_AND_BACK ); + else ok_x4( value, ==, GL_FRONT_AND_BACK ); ext.glGetFramebufferParameterivEXT( 0, GL_READ_BUFFER, &value ); if (broken( amd )) ok_ret( GL_INVALID_ENUM, glGetError() ); else ok_x4( value, ==, GL_BACK ); @@ -3681,10 +3681,10 @@ static void test_framebuffer(void) ok_x4( value, ==, GL_FALSE ); glGetIntegerv( GL_DRAW_BUFFER, &value ); ok_ret( GL_NO_ERROR, glGetError() ); - todo_wine ok_x4( value, ==, GL_FRONT ); + ok_x4( value, ==, GL_FRONT ); glGetIntegerv( GL_READ_BUFFER, &value ); ok_ret( GL_NO_ERROR, glGetError() ); - todo_wine ok_x4( value, ==, GL_FRONT ); + ok_x4( value, ==, GL_FRONT ); glDrawBuffer( GL_FRONT_AND_BACK ); ok_ret( GL_NO_ERROR, glGetError() ); @@ -3692,13 +3692,13 @@ static void test_framebuffer(void) ok_ret( GL_INVALID_OPERATION, glGetError() ); glGetIntegerv( GL_DRAW_BUFFER, &value ); ok_ret( GL_NO_ERROR, glGetError() ); - todo_wine ok_x4( value, ==, GL_FRONT_AND_BACK ); + ok_x4( value, ==, GL_FRONT_AND_BACK ); glGetIntegerv( GL_DRAW_BUFFER1, &value ); ok_ret( GL_NO_ERROR, glGetError() ); ok_x4( value, ==, GL_NONE ); glGetIntegerv( GL_READ_BUFFER, &value ); ok_ret( GL_NO_ERROR, glGetError() ); - todo_wine ok_x4( value, ==, GL_FRONT ); + ok_x4( value, ==, GL_FRONT ); buffers[0] = GL_FRONT_LEFT; buffers[1] = GL_FRONT_LEFT; ext.glDrawBuffers( 2, buffers ); @@ -3713,19 +3713,19 @@ static void test_framebuffer(void) todo_wine ok_ret( GL_INVALID_ENUM, glGetError() ); glGetIntegerv( GL_DRAW_BUFFER, &value ); ok_ret( GL_NO_ERROR, glGetError() ); - todo_wine ok_x4( value, ==, GL_FRONT_AND_BACK ); + ok_x4( value, ==, GL_FRONT_AND_BACK ); glGetIntegerv( GL_DRAW_BUFFER1, &value ); ok_ret( GL_NO_ERROR, glGetError() ); ok_x4( value, ==, GL_NONE ); glGetIntegerv( GL_READ_BUFFER, &value ); ok_ret( GL_NO_ERROR, glGetError() ); - todo_wine ok_x4( value, ==, GL_FRONT ); + ok_x4( value, ==, GL_FRONT ); glReadBuffer( GL_NONE ); ok_ret( GL_NO_ERROR, glGetError() ); glGetIntegerv( GL_DRAW_BUFFER, &value ); ok_ret( GL_NO_ERROR, glGetError() ); - todo_wine ok_x4( value, ==, GL_FRONT_AND_BACK ); + ok_x4( value, ==, GL_FRONT_AND_BACK ); glGetIntegerv( GL_DRAW_BUFFER1, &value ); ok_ret( GL_NO_ERROR, glGetError() ); ok_x4( value, ==, GL_NONE ); @@ -3781,7 +3781,7 @@ static void test_framebuffer(void) ok_x4( status, ==, GL_FRAMEBUFFER_COMPLETE ); glGetIntegerv( GL_DRAW_BUFFER, &value ); ok_ret( GL_NO_ERROR, glGetError() ); - todo_wine ok_x4( value, ==, GL_FRONT_AND_BACK ); + ok_x4( value, ==, GL_FRONT_AND_BACK ); glGetIntegerv( GL_READ_BUFFER, &value ); ok_ret( GL_NO_ERROR, glGetError() ); ok_x4( value, ==, GL_COLOR_ATTACHMENT1 ); @@ -3810,7 +3810,7 @@ static void test_framebuffer(void) glGetIntegerv( GL_DRAW_BUFFER, &value ); ok_ret( GL_NO_ERROR, glGetError() ); - todo_wine ok_x4( value, ==, GL_FRONT_AND_BACK ); + ok_x4( value, ==, GL_FRONT_AND_BACK ); glGetIntegerv( GL_READ_BUFFER, &value ); ok_ret( GL_NO_ERROR, glGetError() ); ok_x4( value, ==, GL_COLOR_ATTACHMENT1 ); @@ -3821,10 +3821,10 @@ static void test_framebuffer(void) todo_wine ok_ret( GL_NO_ERROR, glGetError() ); glGetIntegerv( GL_DRAW_BUFFER, &value ); ok_ret( GL_NO_ERROR, glGetError() ); - todo_wine ok_x4( value, ==, GL_FRONT_LEFT ); + ok_x4( value, ==, GL_FRONT_LEFT ); glGetIntegerv( GL_DRAW_BUFFER1, &value ); ok_ret( GL_NO_ERROR, glGetError() ); - todo_wine ok_x4( value, ==, GL_BACK_LEFT ); + ok_x4( value, ==, GL_BACK_LEFT ); glGetIntegerv( GL_READ_BUFFER, &value ); ok_ret( GL_NO_ERROR, glGetError() ); ok_x4( value, ==, GL_COLOR_ATTACHMENT1 ); @@ -3833,7 +3833,7 @@ static void test_framebuffer(void) ok_ret( GL_NO_ERROR, glGetError() ); glGetIntegerv( GL_DRAW_BUFFER, &value ); ok_ret( GL_NO_ERROR, glGetError() ); - todo_wine ok_x4( value, ==, GL_FRONT_AND_BACK ); + ok_x4( value, ==, GL_FRONT_AND_BACK ); glGetIntegerv( GL_DRAW_BUFFER1, &value ); ok_ret( GL_NO_ERROR, glGetError() ); ok_x4( value, ==, GL_NONE ); @@ -3847,10 +3847,10 @@ static void test_framebuffer(void) todo_wine ok_ret( GL_NO_ERROR, glGetError() ); glGetIntegerv( GL_DRAW_BUFFER, &value ); ok_ret( GL_NO_ERROR, glGetError() ); - todo_wine ok_x4( value, ==, GL_FRONT_LEFT ); + ok_x4( value, ==, GL_FRONT_LEFT ); glGetIntegerv( GL_DRAW_BUFFER1, &value ); ok_ret( GL_NO_ERROR, glGetError() ); - todo_wine ok_x4( value, ==, GL_BACK_LEFT ); + ok_x4( value, ==, GL_BACK_LEFT ); glGetIntegerv( GL_READ_BUFFER, &value ); ok_ret( GL_NO_ERROR, glGetError() ); ok_x4( value, ==, GL_COLOR_ATTACHMENT1 ); diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 26741a40773..ce84d8f9d9b 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -742,27 +742,27 @@ static void set_gl_error( TEB *teb, GLenum error ) static BOOL get_default_fbo_integer( struct context *ctx, struct opengl_drawable *draw, struct opengl_drawable *read, GLenum pname, GLint *data ) { - if (pname == GL_READ_BUFFER && !ctx->read_fbo && read->read_fbo) + if (pname == GL_READ_BUFFER && !ctx->read_fbo) { *data = ctx->pixel_mode.read_buffer; return TRUE; } - if ((pname == GL_DRAW_BUFFER || pname == GL_DRAW_BUFFER0) && !ctx->draw_fbo && draw->draw_fbo) + if ((pname == GL_DRAW_BUFFER || pname == GL_DRAW_BUFFER0) && !ctx->draw_fbo) { *data = ctx->color_buffer.draw_buffers[0]; return TRUE; } - if (pname >= GL_DRAW_BUFFER1 && pname <= GL_DRAW_BUFFER15 && !ctx->draw_fbo && draw->draw_fbo) + if (pname >= GL_DRAW_BUFFER1 && pname <= GL_DRAW_BUFFER15 && !ctx->draw_fbo) { *data = ctx->color_buffer.draw_buffers[pname - GL_DRAW_BUFFER0]; return TRUE; } - if (pname == GL_DOUBLEBUFFER && draw->draw_fbo) + if (pname == GL_DOUBLEBUFFER && !ctx->draw_fbo) { *data = draw->doublebuffer; return TRUE; } - if (pname == GL_STEREO && draw->draw_fbo) + if (pname == GL_STEREO && !ctx->draw_fbo) { *data = draw->stereo; return TRUE; @@ -786,11 +786,9 @@ static BOOL get_integer( TEB *teb, GLenum pname, GLint *data ) switch (pname) { case GL_DRAW_FRAMEBUFFER_BINDING: - if (!draw->draw_fbo) break; *data = ctx->draw_fbo; return TRUE; case GL_READ_FRAMEBUFFER_BINDING: - if (!read->read_fbo) break; *data = ctx->read_fbo; return TRUE; case GL_DEVICE_NODE_MASK_EXT: @@ -1802,8 +1800,11 @@ void wrap_glGetFramebufferParameteriv( TEB *teb, GLuint fbo, GLenum pname, GLint struct opengl_drawable *draw, *read; struct context *ctx; - if ((ctx = get_current_context( teb, &draw, &read )) && !fbo && (fbo = draw->draw_fbo)) + if ((ctx = get_current_context( teb, &draw, &read )) && !fbo) + { if (get_default_fbo_integer( ctx, draw, read, pname, params )) return; + fbo = draw->draw_fbo; + } p_glGetFramebufferParameteriv( fbo, pname, params ); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10784
participants (2)
-
Rémi Bernon -
Rémi Bernon (@rbernon)