From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/make_opengl | 9 ++ dlls/opengl32/unix_thunks.c | 54 ++++-------- dlls/opengl32/unix_thunks.h | 9 ++ dlls/opengl32/unix_wgl.c | 169 ++++++++++++++++++++++++++++++++++++ 4 files changed, 205 insertions(+), 36 deletions(-)
diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index 7a8c294d9ea..5ab4624cff0 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -201,9 +201,14 @@ my %manual_unix_thunks = "glDebugMessageCallback" => 1, "glDebugMessageCallbackAMD" => 1, "glDebugMessageCallbackARB" => 1, + "glDrawBuffer" => 1, + "glDrawBuffers" => 1, "glDrawPixels" => 1, "glFinish" => 1, "glFlush" => 1, + "glFramebufferDrawBufferEXT" => 1, + "glFramebufferDrawBuffersEXT" => 1, + "glFramebufferReadBufferEXT" => 1, "glGetBooleanv" => 1, "glGetDoublev" => 1, "glGetFloatv" => 1, @@ -211,6 +216,10 @@ my %manual_unix_thunks = "glGetIntegerv" => 1, "glGetString" => 1, "glGetStringi" => 1, + "glNamedFramebufferDrawBuffer" => 1, + "glNamedFramebufferDrawBuffers" => 1, + "glNamedFramebufferReadBuffer" => 1, + "glReadBuffer" => 1, "glReadPixels" => 1, "glViewport" => 1, "wglGetProcAddress" => 1, diff --git a/dlls/opengl32/unix_thunks.c b/dlls/opengl32/unix_thunks.c index 23ba4e01854..4c1b1b0b99d 100644 --- a/dlls/opengl32/unix_thunks.c +++ b/dlls/opengl32/unix_thunks.c @@ -699,8 +699,7 @@ static NTSTATUS gl_glDrawArrays( void *args ) static NTSTATUS gl_glDrawBuffer( void *args ) { struct glDrawBuffer_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - funcs->p_glDrawBuffer( params->buf ); + wrap_glDrawBuffer( params->teb, params->buf ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -2189,8 +2188,7 @@ static NTSTATUS gl_glRasterPos4sv( void *args ) static NTSTATUS gl_glReadBuffer( void *args ) { struct glReadBuffer_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - funcs->p_glReadBuffer( params->src ); + wrap_glReadBuffer( params->teb, params->src ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -6864,8 +6862,7 @@ static NTSTATUS ext_glDrawBufferRegion( void *args ) static NTSTATUS ext_glDrawBuffers( void *args ) { struct glDrawBuffers_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - funcs->p_glDrawBuffers( params->n, params->bufs ); + wrap_glDrawBuffers( params->teb, params->n, params->bufs ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -7971,8 +7968,7 @@ static NTSTATUS ext_glFrameZoomSGIX( void *args ) static NTSTATUS ext_glFramebufferDrawBufferEXT( void *args ) { struct glFramebufferDrawBufferEXT_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - funcs->p_glFramebufferDrawBufferEXT( params->framebuffer, params->mode ); + wrap_glFramebufferDrawBufferEXT( params->teb, params->framebuffer, params->mode ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -7980,8 +7976,7 @@ static NTSTATUS ext_glFramebufferDrawBufferEXT( void *args ) static NTSTATUS ext_glFramebufferDrawBuffersEXT( void *args ) { struct glFramebufferDrawBuffersEXT_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - funcs->p_glFramebufferDrawBuffersEXT( params->framebuffer, params->n, params->bufs ); + wrap_glFramebufferDrawBuffersEXT( params->teb, params->framebuffer, params->n, params->bufs ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -8016,8 +8011,7 @@ static NTSTATUS ext_glFramebufferParameteriMESA( void *args ) static NTSTATUS ext_glFramebufferReadBufferEXT( void *args ) { struct glFramebufferReadBufferEXT_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - funcs->p_glFramebufferReadBufferEXT( params->framebuffer, params->mode ); + wrap_glFramebufferReadBufferEXT( params->teb, params->framebuffer, params->mode ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -15464,8 +15458,7 @@ static NTSTATUS ext_glNamedCopyBufferSubDataEXT( void *args ) static NTSTATUS ext_glNamedFramebufferDrawBuffer( void *args ) { struct glNamedFramebufferDrawBuffer_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - funcs->p_glNamedFramebufferDrawBuffer( params->framebuffer, params->buf ); + wrap_glNamedFramebufferDrawBuffer( params->teb, params->framebuffer, params->buf ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -15473,8 +15466,7 @@ static NTSTATUS ext_glNamedFramebufferDrawBuffer( void *args ) static NTSTATUS ext_glNamedFramebufferDrawBuffers( void *args ) { struct glNamedFramebufferDrawBuffers_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - funcs->p_glNamedFramebufferDrawBuffers( params->framebuffer, params->n, params->bufs ); + wrap_glNamedFramebufferDrawBuffers( params->teb, params->framebuffer, params->n, params->bufs ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -15500,8 +15492,7 @@ static NTSTATUS ext_glNamedFramebufferParameteriEXT( void *args ) static NTSTATUS ext_glNamedFramebufferReadBuffer( void *args ) { struct glNamedFramebufferReadBuffer_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - funcs->p_glNamedFramebufferReadBuffer( params->framebuffer, params->src ); + wrap_glNamedFramebufferReadBuffer( params->teb, params->framebuffer, params->src ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -31069,8 +31060,7 @@ static NTSTATUS wow64_gl_glDrawBuffer( void *args ) GLenum buf; } *params = args; TEB *teb = get_teb64( params->teb ); - const struct opengl_funcs *funcs = teb->glTable; - funcs->p_glDrawBuffer( params->buf ); + wrap_glDrawBuffer( teb, params->buf ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -33607,8 +33597,7 @@ static NTSTATUS wow64_gl_glReadBuffer( void *args ) GLenum src; } *params = args; TEB *teb = get_teb64( params->teb ); - const struct opengl_funcs *funcs = teb->glTable; - funcs->p_glReadBuffer( params->src ); + wrap_glReadBuffer( teb, params->src ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -42248,8 +42237,7 @@ static NTSTATUS wow64_ext_glDrawBuffers( void *args ) PTR32 bufs; } *params = args; TEB *teb = get_teb64( params->teb ); - const struct opengl_funcs *funcs = teb->glTable; - funcs->p_glDrawBuffers( params->n, ULongToPtr(params->bufs) ); + wrap_glDrawBuffers( teb, params->n, ULongToPtr(params->bufs) ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -44140,8 +44128,7 @@ static NTSTATUS wow64_ext_glFramebufferDrawBufferEXT( void *args ) GLenum mode; } *params = args; TEB *teb = get_teb64( params->teb ); - const struct opengl_funcs *funcs = teb->glTable; - funcs->p_glFramebufferDrawBufferEXT( params->framebuffer, params->mode ); + wrap_glFramebufferDrawBufferEXT( teb, params->framebuffer, params->mode ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -44156,8 +44143,7 @@ static NTSTATUS wow64_ext_glFramebufferDrawBuffersEXT( void *args ) PTR32 bufs; } *params = args; TEB *teb = get_teb64( params->teb ); - const struct opengl_funcs *funcs = teb->glTable; - funcs->p_glFramebufferDrawBuffersEXT( params->framebuffer, params->n, ULongToPtr(params->bufs) ); + wrap_glFramebufferDrawBuffersEXT( teb, params->framebuffer, params->n, ULongToPtr(params->bufs) ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -44216,8 +44202,7 @@ static NTSTATUS wow64_ext_glFramebufferReadBufferEXT( void *args ) GLenum mode; } *params = args; TEB *teb = get_teb64( params->teb ); - const struct opengl_funcs *funcs = teb->glTable; - funcs->p_glFramebufferReadBufferEXT( params->framebuffer, params->mode ); + wrap_glFramebufferReadBufferEXT( teb, params->framebuffer, params->mode ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -58189,8 +58174,7 @@ static NTSTATUS wow64_ext_glNamedFramebufferDrawBuffer( void *args ) GLenum buf; } *params = args; TEB *teb = get_teb64( params->teb ); - const struct opengl_funcs *funcs = teb->glTable; - funcs->p_glNamedFramebufferDrawBuffer( params->framebuffer, params->buf ); + wrap_glNamedFramebufferDrawBuffer( teb, params->framebuffer, params->buf ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -58205,8 +58189,7 @@ static NTSTATUS wow64_ext_glNamedFramebufferDrawBuffers( void *args ) PTR32 bufs; } *params = args; TEB *teb = get_teb64( params->teb ); - const struct opengl_funcs *funcs = teb->glTable; - funcs->p_glNamedFramebufferDrawBuffers( params->framebuffer, params->n, ULongToPtr(params->bufs) ); + wrap_glNamedFramebufferDrawBuffers( teb, params->framebuffer, params->n, ULongToPtr(params->bufs) ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -58252,8 +58235,7 @@ static NTSTATUS wow64_ext_glNamedFramebufferReadBuffer( void *args ) GLenum src; } *params = args; TEB *teb = get_teb64( params->teb ); - const struct opengl_funcs *funcs = teb->glTable; - funcs->p_glNamedFramebufferReadBuffer( params->framebuffer, params->src ); + wrap_glNamedFramebufferReadBuffer( teb, params->framebuffer, params->src ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } diff --git a/dlls/opengl32/unix_thunks.h b/dlls/opengl32/unix_thunks.h index 7a2074312b0..90b6a43999f 100644 --- a/dlls/opengl32/unix_thunks.h +++ b/dlls/opengl32/unix_thunks.h @@ -8,6 +8,7 @@ extern BOOL wrap_wglMakeCurrent( TEB *teb, HDC hDc, HGLRC newContext ); extern BOOL wrap_wglShareLists( TEB *teb, HGLRC hrcSrvShare, HGLRC hrcSrvSource ); extern BOOL wrap_wglSwapBuffers( TEB *teb, HDC hdc ); extern void wrap_glClear( TEB *teb, GLbitfield mask ); +extern void wrap_glDrawBuffer( TEB *teb, GLenum buf ); extern void wrap_glDrawPixels( TEB *teb, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels ); extern void wrap_glFinish( TEB *teb ); extern void wrap_glFlush( TEB *teb ); @@ -16,13 +17,21 @@ extern void wrap_glGetDoublev( TEB *teb, GLenum pname, GLdouble *data ); extern void wrap_glGetFloatv( TEB *teb, GLenum pname, GLfloat *data ); extern void wrap_glGetIntegerv( TEB *teb, GLenum pname, GLint *data ); extern const GLubyte * wrap_glGetString( TEB *teb, GLenum name ); +extern void wrap_glReadBuffer( TEB *teb, GLenum src ); extern void wrap_glReadPixels( TEB *teb, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels ); extern void wrap_glViewport( TEB *teb, GLint x, GLint y, GLsizei width, GLsizei height ); extern void wrap_glDebugMessageCallback( TEB *teb, GLDEBUGPROC callback, const void *userParam ); extern void wrap_glDebugMessageCallbackAMD( TEB *teb, GLDEBUGPROCAMD callback, void *userParam ); extern void wrap_glDebugMessageCallbackARB( TEB *teb, GLDEBUGPROCARB callback, const void *userParam ); +extern void wrap_glDrawBuffers( TEB *teb, GLsizei n, const GLenum *bufs ); +extern void wrap_glFramebufferDrawBufferEXT( TEB *teb, GLuint framebuffer, GLenum mode ); +extern void wrap_glFramebufferDrawBuffersEXT( TEB *teb, GLuint framebuffer, GLsizei n, const GLenum *bufs ); +extern void wrap_glFramebufferReadBufferEXT( TEB *teb, GLuint framebuffer, GLenum mode ); extern void wrap_glGetInteger64v( TEB *teb, GLenum pname, GLint64 *data ); extern const GLubyte * wrap_glGetStringi( TEB *teb, GLenum name, GLuint index ); +extern void wrap_glNamedFramebufferDrawBuffer( TEB *teb, GLuint framebuffer, GLenum buf ); +extern void wrap_glNamedFramebufferDrawBuffers( TEB *teb, GLuint framebuffer, GLsizei n, const GLenum *bufs ); +extern void wrap_glNamedFramebufferReadBuffer( TEB *teb, GLuint framebuffer, GLenum src ); extern BOOL wrap_wglBindTexImageARB( TEB *teb, HPBUFFERARB hPbuffer, int iBuffer ); extern HGLRC wrap_wglCreateContextAttribsARB( TEB *teb, HDC hDC, HGLRC hShareContext, const int *attribList ); extern HPBUFFERARB wrap_wglCreatePbufferARB( TEB *teb, HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList ); diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index ea3c46e98bc..a74deefeb51 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -65,6 +65,11 @@ enum wgl_handle_type
/* context state management */
+struct pixel_mode_state +{ + GLenum read_buffer; +}; + struct light_model_state { GLfloat ambient[4]; @@ -100,9 +105,12 @@ struct enable_state GLboolean normalize; };
+#define MAX_DRAW_BUFFERS 16 + struct color_buffer_state { GLfloat clear_color[4]; + GLenum draw_buffers[MAX_DRAW_BUFFERS]; };
struct hint_state @@ -126,6 +134,7 @@ struct context
/* semi-stub state tracker for wglCopyContext */ GLbitfield used; /* context state used bits */ + struct pixel_mode_state pixel_mode; /* GL_PIXEL_MODE_BIT */ struct lighting_state lighting; /* GL_LIGHTING_BIT */ struct depth_buffer_state depth_buffer; /* GL_DEPTH_BUFFER_BIT */ struct viewport_state viewport; /* GL_VIEWPORT_BIT */ @@ -1404,6 +1413,166 @@ void set_current_fbo( TEB *teb, GLenum target, GLuint fbo ) if (target == GL_READ_FRAMEBUFFER) ctx->read_fbo = fbo; }
+static void set_default_fbo_draw_buffers( struct context *ctx, struct opengl_drawable *draw, + GLsizei count, const GLenum *buffers ) +{ + memset( ctx->color_buffer.draw_buffers, 0, sizeof(ctx->color_buffer.draw_buffers) ); + + for (GLsizei i = 0; i < count; i++) + { + if (i >= MAX_DRAW_BUFFERS) FIXME( "Needs %u draw buffers\n", i ); + else ctx->color_buffer.draw_buffers[i] = buffers[i]; + } +} + +void wrap_glDrawBuffers( TEB *teb, GLsizei n, const GLenum *bufs ) +{ + struct opengl_funcs *funcs = teb->glTable; + struct opengl_drawable *draw; + struct context *ctx; + + if ((ctx = get_current_context( teb, &draw, NULL )) && !ctx->draw_fbo && draw->fbo) + set_default_fbo_draw_buffers( ctx, draw, n, bufs ); + + funcs->p_glDrawBuffers( n, bufs ); +} + +void wrap_glFramebufferDrawBuffersEXT( TEB *teb, GLuint fbo, GLsizei n, const GLenum *bufs ) +{ + struct opengl_funcs *funcs = teb->glTable; + struct opengl_drawable *draw; + struct context *ctx; + + if ((ctx = get_current_context( teb, &draw, NULL )) && !fbo && draw->fbo) + set_default_fbo_draw_buffers( ctx, draw, n, bufs ); + + funcs->p_glFramebufferDrawBuffersEXT( fbo, n, bufs ); +} + +void wrap_glNamedFramebufferDrawBuffers( TEB *teb, GLuint fbo, GLsizei n, const GLenum *bufs ) +{ + struct opengl_funcs *funcs = teb->glTable; + struct opengl_drawable *draw; + struct context *ctx; + + if ((ctx = get_current_context( teb, &draw, NULL )) && !fbo && draw->fbo) + set_default_fbo_draw_buffers( ctx, draw, n, bufs ); + + funcs->p_glNamedFramebufferDrawBuffers( fbo, n, bufs ); +} + +static void set_default_fbo_draw_buffer( struct context *ctx, struct opengl_drawable *draw, GLint buffer ) +{ + switch (buffer) + { + case GL_LEFT: + case GL_RIGHT: + case GL_FRONT: + case GL_BACK: + case GL_FRONT_AND_BACK: + case GL_FRONT_LEFT: + case GL_FRONT_RIGHT: + case GL_BACK_LEFT: + case GL_BACK_RIGHT: + memset( ctx->color_buffer.draw_buffers, 0, sizeof(ctx->color_buffer.draw_buffers) ); + ctx->color_buffer.draw_buffers[0] = buffer; + return; + } + + WARN( "Invalid draw buffer %#x for context %p\n", buffer, ctx ); +} + +void wrap_glDrawBuffer( TEB *teb, GLenum buf ) +{ + const struct opengl_funcs *funcs = teb->glTable; + struct opengl_drawable *draw; + struct context *ctx; + + if ((ctx = get_current_context( teb, &draw, NULL )) && !ctx->draw_fbo && draw->fbo) + set_default_fbo_draw_buffer( ctx, draw, buf ); + + funcs->p_glDrawBuffer( buf ); +} + +void wrap_glFramebufferDrawBufferEXT( TEB *teb, GLuint fbo, GLenum mode ) +{ + const struct opengl_funcs *funcs = teb->glTable; + struct opengl_drawable *draw; + struct context *ctx; + + if ((ctx = get_current_context( teb, &draw, NULL )) && !fbo && draw->fbo) + set_default_fbo_draw_buffer( ctx, draw, mode ); + + funcs->p_glFramebufferDrawBufferEXT( fbo, mode ); +} + +void wrap_glNamedFramebufferDrawBuffer( TEB *teb, GLuint fbo, GLenum buf ) +{ + const struct opengl_funcs *funcs = teb->glTable; + struct opengl_drawable *draw; + struct context *ctx; + + if ((ctx = get_current_context( teb, &draw, NULL )) && !fbo && draw->fbo) + set_default_fbo_draw_buffer( ctx, draw, buf ); + + funcs->p_glNamedFramebufferDrawBuffer( fbo, buf ); +} + +static void set_default_fbo_read_buffer( struct context *ctx, struct opengl_drawable *read, GLint buffer ) +{ + switch (buffer) + { + case GL_FRONT: + case GL_LEFT: + case GL_FRONT_LEFT: + case GL_RIGHT: + case GL_FRONT_RIGHT: + case GL_BACK: + case GL_BACK_LEFT: + case GL_BACK_RIGHT: + ctx->pixel_mode.read_buffer = buffer; + return; + } + + WARN( "Invalid read buffer %#x for context %p\n", buffer, ctx ); +} + +void wrap_glReadBuffer( TEB *teb, GLenum src ) +{ + const struct opengl_funcs *funcs = teb->glTable; + struct opengl_drawable *read; + struct context *ctx; + + if ((ctx = get_current_context( teb, NULL, &read )) && !ctx->read_fbo && read->fbo) + set_default_fbo_read_buffer( ctx, read, src ); + + funcs->p_glReadBuffer( src ); +} + +void wrap_glFramebufferReadBufferEXT( TEB *teb, GLuint fbo, GLenum mode ) +{ + const struct opengl_funcs *funcs = teb->glTable; + struct opengl_drawable *read; + struct context *ctx; + + if ((ctx = get_current_context( teb, NULL, &read )) && !fbo && read->fbo) + set_default_fbo_read_buffer( ctx, read, mode ); + + funcs->p_glFramebufferReadBufferEXT( fbo, mode ); +} + +void wrap_glNamedFramebufferReadBuffer( TEB *teb, GLuint fbo, GLenum src ) +{ + const struct opengl_funcs *funcs = teb->glTable; + struct opengl_drawable *read; + struct context *ctx; + + if ((ctx = get_current_context( teb, NULL, &read )) && !fbo && read->fbo) + set_default_fbo_read_buffer( ctx, read, src ); + + funcs->p_glNamedFramebufferReadBuffer( fbo, src ); +} + void wrap_glGetIntegerv( TEB *teb, GLenum pname, GLint *data ) { const struct opengl_funcs *funcs = teb->glTable;