[PATCH 08/12] wined3d: Add support for ARB_framebuffer_object.

Henri Verbeet hverbeet at codeweavers.com
Wed Sep 23 03:05:55 CDT 2009


---
 dlls/wined3d/context.c    |  104 +++++++++++++++++++++++----------------------
 dlls/wined3d/device.c     |   53 +++++++++++++---------
 dlls/wined3d/directx.c    |   61 ++++++++++++++++++++++++--
 dlls/wined3d/surface.c    |   55 ++++++++++++++---------
 dlls/wined3d/utils.c      |   93 ++++++++++++++++++++++------------------
 dlls/wined3d/wined3d_gl.h |   24 ++++++++++
 6 files changed, 250 insertions(+), 140 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 28cd4a0..878e5bf 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -48,8 +48,8 @@ void context_bind_fbo(struct wined3d_context *context, GLenum target, GLuint *fb
     {
         if (!*fbo)
         {
-            GL_EXTCALL(glGenFramebuffersEXT(1, fbo));
-            checkGLcall("glGenFramebuffersEXT()");
+            gl_info->fbo_ops.glGenFramebuffers(1, fbo);
+            checkGLcall("glGenFramebuffers()");
             TRACE("Created FBO %u.\n", *fbo);
         }
         f = *fbo;
@@ -57,17 +57,17 @@ void context_bind_fbo(struct wined3d_context *context, GLenum target, GLuint *fb
 
     switch (target)
     {
-        case GL_READ_FRAMEBUFFER_EXT:
+        case GL_READ_FRAMEBUFFER:
             if (context->fbo_read_binding == f) return;
             context->fbo_read_binding = f;
             break;
 
-        case GL_DRAW_FRAMEBUFFER_EXT:
+        case GL_DRAW_FRAMEBUFFER:
             if (context->fbo_draw_binding == f) return;
             context->fbo_draw_binding = f;
             break;
 
-        case GL_FRAMEBUFFER_EXT:
+        case GL_FRAMEBUFFER:
             if (context->fbo_read_binding == f
                     && context->fbo_draw_binding == f) return;
             context->fbo_read_binding = f;
@@ -79,7 +79,7 @@ void context_bind_fbo(struct wined3d_context *context, GLenum target, GLuint *fb
             break;
     }
 
-    GL_EXTCALL(glBindFramebufferEXT(target, f));
+    gl_info->fbo_ops.glBindFramebuffer(target, f);
     checkGLcall("glBindFramebuffer()");
 }
 
@@ -90,13 +90,13 @@ static void context_clean_fbo_attachments(const struct wined3d_gl_info *gl_info)
 
     for (i = 0; i < GL_LIMITS(buffers); ++i)
     {
-        GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + i, GL_TEXTURE_2D, 0, 0));
+        gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, 0, 0);
         checkGLcall("glFramebufferTexture2D()");
     }
-    GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
+    gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
     checkGLcall("glFramebufferTexture2D()");
 
-    GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
+    gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
     checkGLcall("glFramebufferTexture2D()");
 }
 
@@ -105,11 +105,11 @@ static void context_destroy_fbo(struct wined3d_context *context, GLuint *fbo)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
 
-    context_bind_fbo(context, GL_FRAMEBUFFER_EXT, fbo);
+    context_bind_fbo(context, GL_FRAMEBUFFER, fbo);
     context_clean_fbo_attachments(gl_info);
-    context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL);
+    context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
 
-    GL_EXTCALL(glDeleteFramebuffersEXT(1, fbo));
+    gl_info->fbo_ops.glDeleteFramebuffers(1, fbo);
     checkGLcall("glDeleteFramebuffers()");
 }
 
@@ -194,16 +194,16 @@ void context_attach_depth_stencil_fbo(struct wined3d_context *context,
         {
             if (format_flags & WINED3DFMT_FLAG_DEPTH)
             {
-                GL_EXTCALL(glFramebufferRenderbufferEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT,
-                        GL_RENDERBUFFER_EXT, depth_stencil_impl->current_renderbuffer->id));
-                checkGLcall("glFramebufferRenderbufferEXT()");
+                gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_DEPTH_ATTACHMENT,
+                        GL_RENDERBUFFER, depth_stencil_impl->current_renderbuffer->id);
+                checkGLcall("glFramebufferRenderbuffer()");
             }
 
             if (format_flags & WINED3DFMT_FLAG_STENCIL)
             {
-                GL_EXTCALL(glFramebufferRenderbufferEXT(fbo_target, GL_STENCIL_ATTACHMENT_EXT,
-                        GL_RENDERBUFFER_EXT, depth_stencil_impl->current_renderbuffer->id));
-                checkGLcall("glFramebufferRenderbufferEXT()");
+                gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_STENCIL_ATTACHMENT,
+                        GL_RENDERBUFFER, depth_stencil_impl->current_renderbuffer->id);
+                checkGLcall("glFramebufferRenderbuffer()");
             }
         }
         else
@@ -212,40 +212,40 @@ void context_attach_depth_stencil_fbo(struct wined3d_context *context,
 
             if (format_flags & WINED3DFMT_FLAG_DEPTH)
             {
-                GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT,
+                gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT,
                         depth_stencil_impl->texture_target, depth_stencil_impl->texture_name,
-                        depth_stencil_impl->texture_level));
-                checkGLcall("glFramebufferTexture2DEXT()");
+                        depth_stencil_impl->texture_level);
+                checkGLcall("glFramebufferTexture2D()");
             }
 
             if (format_flags & WINED3DFMT_FLAG_STENCIL)
             {
-                GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_STENCIL_ATTACHMENT_EXT,
+                gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT,
                         depth_stencil_impl->texture_target, depth_stencil_impl->texture_name,
-                        depth_stencil_impl->texture_level));
-                checkGLcall("glFramebufferTexture2DEXT()");
+                        depth_stencil_impl->texture_level);
+                checkGLcall("glFramebufferTexture2D()");
             }
         }
 
         if (!(format_flags & WINED3DFMT_FLAG_DEPTH))
         {
-            GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
-            checkGLcall("glFramebufferTexture2DEXT()");
+            gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
+            checkGLcall("glFramebufferTexture2D()");
         }
 
         if (!(format_flags & WINED3DFMT_FLAG_STENCIL))
         {
-            GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
-            checkGLcall("glFramebufferTexture2DEXT()");
+            gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
+            checkGLcall("glFramebufferTexture2D()");
         }
     }
     else
     {
-        GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
-        checkGLcall("glFramebufferTexture2DEXT()");
+        gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
+        checkGLcall("glFramebufferTexture2D()");
 
-        GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
-        checkGLcall("glFramebufferTexture2DEXT()");
+        gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
+        checkGLcall("glFramebufferTexture2D()");
     }
 }
 
@@ -262,12 +262,14 @@ void context_attach_surface_fbo(const struct wined3d_context *context,
     {
         context_apply_attachment_filter_states(surface, TRUE);
 
-        GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_COLOR_ATTACHMENT0_EXT + idx, surface_impl->texture_target,
-                surface_impl->texture_name, surface_impl->texture_level));
-        checkGLcall("glFramebufferTexture2DEXT()");
-    } else {
-        GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_COLOR_ATTACHMENT0_EXT + idx, GL_TEXTURE_2D, 0, 0));
-        checkGLcall("glFramebufferTexture2DEXT()");
+        gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx, surface_impl->texture_target,
+                surface_impl->texture_name, surface_impl->texture_level);
+        checkGLcall("glFramebufferTexture2D()");
+    }
+    else
+    {
+        gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx, GL_TEXTURE_2D, 0, 0);
+        checkGLcall("glFramebufferTexture2D()");
     }
 }
 
@@ -277,8 +279,8 @@ static void context_check_fbo_status(struct wined3d_context *context)
     const struct wined3d_gl_info *gl_info = context->gl_info;
     GLenum status;
 
-    status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
-    if (status == GL_FRAMEBUFFER_COMPLETE_EXT)
+    status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
+    if (status == GL_FRAMEBUFFER_COMPLETE)
     {
         TRACE("FBO complete\n");
     } else {
@@ -329,7 +331,7 @@ static void context_reuse_fbo_entry(struct wined3d_context *context, struct fbo_
     IWineD3DDeviceImpl *device = ((IWineD3DSurfaceImpl *)context->surface)->resource.wineD3DDevice;
     const struct wined3d_gl_info *gl_info = context->gl_info;
 
-    context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &entry->id);
+    context_bind_fbo(context, GL_FRAMEBUFFER, &entry->id);
     context_clean_fbo_attachments(gl_info);
 
     memcpy(entry->render_targets, device->render_targets, GL_LIMITS(buffers) * sizeof(*entry->render_targets));
@@ -394,7 +396,7 @@ static void context_apply_fbo_entry(struct wined3d_context *context, struct fbo_
     const struct wined3d_gl_info *gl_info = context->gl_info;
     unsigned int i;
 
-    context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &entry->id);
+    context_bind_fbo(context, GL_FRAMEBUFFER, &entry->id);
 
     if (!entry->attached)
     {
@@ -402,7 +404,7 @@ static void context_apply_fbo_entry(struct wined3d_context *context, struct fbo_
         for (i = 0; i < GL_LIMITS(buffers); ++i)
         {
             IWineD3DSurface *render_target = device->render_targets[i];
-            context_attach_surface_fbo(context, GL_FRAMEBUFFER_EXT, i, render_target);
+            context_attach_surface_fbo(context, GL_FRAMEBUFFER, i, render_target);
         }
 
         /* Apply depth targets */
@@ -413,7 +415,7 @@ static void context_apply_fbo_entry(struct wined3d_context *context, struct fbo_
 
             surface_set_compatible_renderbuffer(device->stencilBufferTarget, w, h);
         }
-        context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER_EXT, device->stencilBufferTarget, TRUE);
+        context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, device->stencilBufferTarget, TRUE);
 
         entry->attached = TRUE;
     } else {
@@ -429,7 +431,7 @@ static void context_apply_fbo_entry(struct wined3d_context *context, struct fbo_
     for (i = 0; i < GL_LIMITS(buffers); ++i)
     {
         if (device->render_targets[i])
-            device->draw_buffers[i] = GL_COLOR_ATTACHMENT0_EXT + i;
+            device->draw_buffers[i] = GL_COLOR_ATTACHMENT0 + i;
         else
             device->draw_buffers[i] = GL_NONE;
     }
@@ -444,7 +446,7 @@ static void context_apply_fbo_state(struct wined3d_context *context)
         context_apply_fbo_entry(context, context->current_fbo);
     } else {
         context->current_fbo = NULL;
-        context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL);
+        context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
     }
 
     context_check_fbo_status(context);
@@ -1958,7 +1960,7 @@ static void context_apply_draw_buffer(struct wined3d_context *context, BOOL blit
                     checkGLcall("glDrawBuffer()");
                 }
             } else {
-                glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
+                glDrawBuffer(GL_COLOR_ATTACHMENT0);
                 checkGLcall("glDrawBuffer()");
             }
         }
@@ -2040,13 +2042,13 @@ struct wined3d_context *ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurfac
                 {
                     FIXME("Activating for CTXUSAGE_BLIT for an offscreen target with ORM_FBO. This should be avoided.\n");
                     ENTER_GL();
-                    context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &context->dst_fbo);
-                    context_attach_surface_fbo(context, GL_FRAMEBUFFER_EXT, 0, target);
-                    context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER_EXT, NULL, FALSE);
+                    context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo);
+                    context_attach_surface_fbo(context, GL_FRAMEBUFFER, 0, target);
+                    context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, NULL, FALSE);
                     LEAVE_GL();
                 } else {
                     ENTER_GL();
-                    context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL);
+                    context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
                     LEAVE_GL();
                 }
                 context->draw_buffer_dirty = TRUE;
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 17f51a8..30912f1 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -2210,6 +2210,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface,
         D3DCB_DESTROYSWAPCHAINFN D3DCB_DestroySwapChain)
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
+    const struct wined3d_context *context;
+    const struct wined3d_gl_info *gl_info;
     int sampler;
     UINT i;
     TRACE("(%p)\n", This);
@@ -2219,7 +2221,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface,
     /* I don't think that the interface guarantees that the device is destroyed from the same thread
      * it was created. Thus make sure a context is active for the glDelete* calls
      */
-    ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
+    context = ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
+    gl_info = context->gl_info;
 
     if(This->logo_surface) IWineD3DSurface_Release(This->logo_surface);
 
@@ -2273,7 +2276,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface,
     }
     if (This->depth_blt_rb) {
         ENTER_GL();
-        GL_EXTCALL(glDeleteRenderbuffersEXT(1, &This->depth_blt_rb));
+        gl_info->fbo_ops.glDeleteRenderbuffers(1, &This->depth_blt_rb);
         LEAVE_GL();
         This->depth_blt_rb = 0;
         This->depth_blt_rb_w = 0;
@@ -5952,7 +5955,7 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface,
 
         context = ActivateContext(This, surface, CTXUSAGE_RESOURCELOAD);
         ENTER_GL();
-        context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL);
+        context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
         buffer = surface_get_gl_buffer(surface, swapchain);
         glDrawBuffer(buffer);
         checkGLcall("glDrawBuffer()");
@@ -5961,9 +5964,9 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface,
 
         context = ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
         ENTER_GL();
-        context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &context->dst_fbo);
-        context_attach_surface_fbo(context, GL_FRAMEBUFFER_EXT, 0, surface);
-        context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER_EXT, NULL, FALSE);
+        context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo);
+        context_attach_surface_fbo(context, GL_FRAMEBUFFER, 0, surface);
+        context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, NULL, FALSE);
     }
 
     if (rect) {
@@ -6320,6 +6323,7 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     GLbitfield mask = GL_COLOR_BUFFER_BIT; /* TODO: Support blitting depth/stencil surfaces */
     IWineD3DSwapChain *src_swapchain, *dst_swapchain;
+    const struct wined3d_gl_info *gl_info;
     struct wined3d_context *context;
     GLenum gl_filter;
     POINT offset = {0, 0};
@@ -6350,6 +6354,8 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
     else if (dst_swapchain) context = ActivateContext(This, dst_surface, CTXUSAGE_RESOURCELOAD);
     else context = ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
 
+    gl_info = context->gl_info;
+
     if (src_swapchain) {
         GLenum buffer = surface_get_gl_buffer(src_surface, src_swapchain);
 
@@ -6373,17 +6379,17 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
         }
 
         ENTER_GL();
-        context_bind_fbo(context, GL_READ_FRAMEBUFFER_EXT, NULL);
+        context_bind_fbo(context, GL_READ_FRAMEBUFFER, NULL);
         glReadBuffer(buffer);
         checkGLcall("glReadBuffer()");
     } else {
         TRACE("Source surface %p is offscreen\n", src_surface);
         ENTER_GL();
-        context_bind_fbo(context, GL_READ_FRAMEBUFFER_EXT, &context->src_fbo);
-        context_attach_surface_fbo(context, GL_READ_FRAMEBUFFER_EXT, 0, src_surface);
-        glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
+        context_bind_fbo(context, GL_READ_FRAMEBUFFER, &context->src_fbo);
+        context_attach_surface_fbo(context, GL_READ_FRAMEBUFFER, 0, src_surface);
+        glReadBuffer(GL_COLOR_ATTACHMENT0);
         checkGLcall("glReadBuffer()");
-        context_attach_depth_stencil_fbo(context, GL_READ_FRAMEBUFFER_EXT, NULL, FALSE);
+        context_attach_depth_stencil_fbo(context, GL_READ_FRAMEBUFFER, NULL, FALSE);
     }
     LEAVE_GL();
 
@@ -6412,29 +6418,29 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
         }
 
         ENTER_GL();
-        context_bind_fbo(context, GL_DRAW_FRAMEBUFFER_EXT, NULL);
+        context_bind_fbo(context, GL_DRAW_FRAMEBUFFER, NULL);
         glDrawBuffer(buffer);
         checkGLcall("glDrawBuffer()");
     } else {
         TRACE("Destination surface %p is offscreen\n", dst_surface);
 
         ENTER_GL();
-        context_bind_fbo(context, GL_DRAW_FRAMEBUFFER_EXT, &context->dst_fbo);
-        context_attach_surface_fbo(context, GL_DRAW_FRAMEBUFFER_EXT, 0, dst_surface);
-        glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
+        context_bind_fbo(context, GL_DRAW_FRAMEBUFFER, &context->dst_fbo);
+        context_attach_surface_fbo(context, GL_DRAW_FRAMEBUFFER, 0, dst_surface);
+        glDrawBuffer(GL_COLOR_ATTACHMENT0);
         checkGLcall("glDrawBuffer()");
-        context_attach_depth_stencil_fbo(context, GL_DRAW_FRAMEBUFFER_EXT, NULL, FALSE);
+        context_attach_depth_stencil_fbo(context, GL_DRAW_FRAMEBUFFER, NULL, FALSE);
     }
     glDisable(GL_SCISSOR_TEST);
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE));
 
     if (flip) {
-        GL_EXTCALL(glBlitFramebufferEXT(src_rect->x1, src_rect->y1, src_rect->x2, src_rect->y2,
-                dst_rect->x1, dst_rect->y2, dst_rect->x2, dst_rect->y1, mask, gl_filter));
+        gl_info->fbo_ops.glBlitFramebuffer(src_rect->x1, src_rect->y1, src_rect->x2, src_rect->y2,
+                dst_rect->x1, dst_rect->y2, dst_rect->x2, dst_rect->y1, mask, gl_filter);
         checkGLcall("glBlitFramebuffer()");
     } else {
-        GL_EXTCALL(glBlitFramebufferEXT(src_rect->x1, src_rect->y1, src_rect->x2, src_rect->y2,
-                dst_rect->x1, dst_rect->y1, dst_rect->x2, dst_rect->y2, mask, gl_filter));
+        gl_info->fbo_ops.glBlitFramebuffer(src_rect->x1, src_rect->y1, src_rect->x2, src_rect->y2,
+                dst_rect->x1, dst_rect->y1, dst_rect->x2, dst_rect->y2, mask, gl_filter);
         checkGLcall("glBlitFramebuffer()");
     }
 
@@ -6878,10 +6884,13 @@ static BOOL is_display_mode_supported(IWineD3DDeviceImpl *This, const WINED3DPRE
 void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain_iface) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
     IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) swapchain_iface;
+    const struct wined3d_context *context;
+    const struct wined3d_gl_info *gl_info;
     UINT i;
     IWineD3DBaseShaderImpl *shader;
 
-    ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
+    context = ActivateContext(This, NULL, CTXUSAGE_RESOURCELOAD);
+    gl_info = context->gl_info;
 
     IWineD3DDevice_EnumResources(iface, reset_unload_resources, NULL);
     LIST_FOR_EACH_ENTRY(shader, &This->shaders, IWineD3DBaseShaderImpl, baseShader.shader_list_entry) {
@@ -6894,7 +6903,7 @@ void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain_
         This->depth_blt_texture = 0;
     }
     if (This->depth_blt_rb) {
-        GL_EXTCALL(glDeleteRenderbuffersEXT(1, &This->depth_blt_rb));
+        gl_info->fbo_ops.glDeleteRenderbuffers(1, &This->depth_blt_rb);
         This->depth_blt_rb = 0;
         This->depth_blt_rb_w = 0;
         This->depth_blt_rb_h = 0;
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 5c94681..2f4cdae 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -1872,10 +1872,63 @@ static BOOL IWineD3DImpl_FillGLCaps(struct wined3d_gl_info *gl_info)
      * shaders), but 8 texture stages (register combiners). */
     gl_info->max_sampler_stages = max(gl_info->max_fragment_samplers, gl_info->max_texture_stages);
 
-    /* We can only use ORM_FBO when the hardware supports it. */
-    if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && !gl_info->supported[EXT_FRAMEBUFFER_OBJECT]) {
-        WARN_(d3d_caps)("GL_EXT_framebuffer_object not supported, falling back to backbuffer offscreen rendering mode.\n");
-        wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER;
+    if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
+    {
+        gl_info->fbo_ops.glIsRenderbuffer = gl_info->glIsRenderbuffer;
+        gl_info->fbo_ops.glBindRenderbuffer = gl_info->glBindRenderbuffer;
+        gl_info->fbo_ops.glDeleteRenderbuffers = gl_info->glDeleteRenderbuffers;
+        gl_info->fbo_ops.glGenRenderbuffers = gl_info->glGenRenderbuffers;
+        gl_info->fbo_ops.glRenderbufferStorage = gl_info->glRenderbufferStorage;
+        gl_info->fbo_ops.glRenderbufferStorageMultisample = gl_info->glRenderbufferStorageMultisample;
+        gl_info->fbo_ops.glGetRenderbufferParameteriv = gl_info->glGetRenderbufferParameteriv;
+        gl_info->fbo_ops.glIsFramebuffer = gl_info->glIsFramebuffer;
+        gl_info->fbo_ops.glBindFramebuffer = gl_info->glBindFramebuffer;
+        gl_info->fbo_ops.glDeleteFramebuffers = gl_info->glDeleteFramebuffers;
+        gl_info->fbo_ops.glGenFramebuffers = gl_info->glGenFramebuffers;
+        gl_info->fbo_ops.glCheckFramebufferStatus = gl_info->glCheckFramebufferStatus;
+        gl_info->fbo_ops.glFramebufferTexture1D = gl_info->glFramebufferTexture1D;
+        gl_info->fbo_ops.glFramebufferTexture2D = gl_info->glFramebufferTexture2D;
+        gl_info->fbo_ops.glFramebufferTexture3D = gl_info->glFramebufferTexture3D;
+        gl_info->fbo_ops.glFramebufferRenderbuffer = gl_info->glFramebufferRenderbuffer;
+        gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv = gl_info->glGetFramebufferAttachmentParameteriv;
+        gl_info->fbo_ops.glBlitFramebuffer = gl_info->glBlitFramebuffer;
+        gl_info->fbo_ops.glGenerateMipmap = gl_info->glGenerateMipmap;
+    }
+    else
+    {
+        if (gl_info->supported[EXT_FRAMEBUFFER_OBJECT])
+        {
+            gl_info->fbo_ops.glIsRenderbuffer = gl_info->glIsRenderbufferEXT;
+            gl_info->fbo_ops.glBindRenderbuffer = gl_info->glBindRenderbufferEXT;
+            gl_info->fbo_ops.glDeleteRenderbuffers = gl_info->glDeleteRenderbuffersEXT;
+            gl_info->fbo_ops.glGenRenderbuffers = gl_info->glGenRenderbuffersEXT;
+            gl_info->fbo_ops.glRenderbufferStorage = gl_info->glRenderbufferStorageEXT;
+            gl_info->fbo_ops.glGetRenderbufferParameteriv = gl_info->glGetRenderbufferParameterivEXT;
+            gl_info->fbo_ops.glIsFramebuffer = gl_info->glIsFramebufferEXT;
+            gl_info->fbo_ops.glBindFramebuffer = gl_info->glBindFramebufferEXT;
+            gl_info->fbo_ops.glDeleteFramebuffers = gl_info->glDeleteFramebuffersEXT;
+            gl_info->fbo_ops.glGenFramebuffers = gl_info->glGenFramebuffersEXT;
+            gl_info->fbo_ops.glCheckFramebufferStatus = gl_info->glCheckFramebufferStatusEXT;
+            gl_info->fbo_ops.glFramebufferTexture1D = gl_info->glFramebufferTexture1DEXT;
+            gl_info->fbo_ops.glFramebufferTexture2D = gl_info->glFramebufferTexture2DEXT;
+            gl_info->fbo_ops.glFramebufferTexture3D = gl_info->glFramebufferTexture3DEXT;
+            gl_info->fbo_ops.glFramebufferRenderbuffer = gl_info->glFramebufferRenderbufferEXT;
+            gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv = gl_info->glGetFramebufferAttachmentParameterivEXT;
+            gl_info->fbo_ops.glGenerateMipmap = gl_info->glGenerateMipmapEXT;
+        }
+        else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+        {
+            WARN_(d3d_caps)("Framebuffer objects not supported, falling back to backbuffer offscreen rendering mode.\n");
+            wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER;
+        }
+        if (gl_info->supported[EXT_FRAMEBUFFER_BLIT])
+        {
+            gl_info->fbo_ops.glBlitFramebuffer = gl_info->glBlitFramebufferEXT;
+        }
+        if (gl_info->supported[EXT_FRAMEBUFFER_MULTISAMPLE])
+        {
+            gl_info->fbo_ops.glRenderbufferStorageMultisample = gl_info->glRenderbufferStorageMultisampleEXT;
+        }
     }
 
     /* MRTs are currently only supported when FBOs are used. */
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 6a5e66d..564f6b3 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -70,7 +70,7 @@ static void surface_cleanup(IWineD3DSurfaceImpl *This)
 
     LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &This->renderbuffers, renderbuffer_entry_t, entry)
     {
-        GL_EXTCALL(glDeleteRenderbuffersEXT(1, &entry->id));
+        gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
         HeapFree(GetProcessHeap(), 0, entry);
     }
 
@@ -610,6 +610,7 @@ static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal,
 /* GL locking is done by the caller */
 void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int width, unsigned int height) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
+    const struct wined3d_gl_info *gl_info = &This->resource.wineD3DDevice->adapter->gl_info;
     renderbuffer_entry_t *entry;
     GLuint renderbuffer = 0;
     unsigned int src_width, src_height;
@@ -636,10 +637,10 @@ void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int wi
     }
 
     if (!renderbuffer) {
-        GL_EXTCALL(glGenRenderbuffersEXT(1, &renderbuffer));
-        GL_EXTCALL(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderbuffer));
-        GL_EXTCALL(glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
-                This->resource.format_desc->glInternal, width, height));
+        gl_info->fbo_ops.glGenRenderbuffers(1, &renderbuffer);
+        gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
+        gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER,
+                This->resource.format_desc->glInternal, width, height);
 
         entry = HeapAlloc(GetProcessHeap(), 0, sizeof(renderbuffer_entry_t));
         entry->width = width;
@@ -814,6 +815,8 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) {
     IWineD3DBaseTexture *texture = NULL;
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
     IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
+    const struct wined3d_context *context;
+    const struct wined3d_gl_info *gl_info;
     renderbuffer_entry_t *entry, *entry2;
     TRACE("(%p)\n", iface);
 
@@ -844,7 +847,8 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) {
     IWineD3DSurface_ModifyLocation(iface, SFLAG_INSRGBTEX, FALSE);
     This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
 
-    ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
+    context = ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
+    gl_info = context->gl_info;
 
     /* Destroy PBOs, but load them into real sysmem before */
     if(This->Flags & SFLAG_PBO) {
@@ -857,7 +861,7 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) {
      */
     LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &This->renderbuffers, renderbuffer_entry_t, entry) {
         ENTER_GL();
-        GL_EXTCALL(glDeleteRenderbuffersEXT(1, &entry->id));
+        gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
         LEAVE_GL();
         list_remove(&entry->entry);
         HeapFree(GetProcessHeap(), 0, entry);
@@ -1885,7 +1889,8 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
             break;
 
         case WINED3DFMT_D15S1:
-            if (GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL))
+            if (GL_SUPPORT(ARB_FRAMEBUFFER_OBJECT)
+                    || GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL))
             {
                 *convert = CONVERT_D15S1;
                 *target_bpp = 4;
@@ -1893,7 +1898,8 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
             break;
 
         case WINED3DFMT_D24X4S4:
-            if (GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL))
+            if (GL_SUPPORT(ARB_FRAMEBUFFER_OBJECT)
+                    || GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL))
             {
                 *convert = CONVERT_D24X4S4;
             }
@@ -3581,7 +3587,8 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const
          * FBO support, so it doesn't really make sense to try and make it work with different offscreen rendering
          * backends.
          */
-        if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && GL_SUPPORT(EXT_FRAMEBUFFER_BLIT)
+        if (wined3d_settings.offscreen_rendering_mode == ORM_FBO
+                && myDevice->adapter->gl_info.fbo_ops.glBlitFramebuffer
                 && surface_can_stretch_rect(Src, This))
         {
             stretch_rect_fbo((IWineD3DDevice *)myDevice, SrcSurface, &srect,
@@ -3645,7 +3652,8 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const
             Src->palette = This->palette;
         }
 
-        if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && GL_SUPPORT(EXT_FRAMEBUFFER_BLIT)
+        if (wined3d_settings.offscreen_rendering_mode == ORM_FBO
+                && myDevice->adapter->gl_info.fbo_ops.glBlitFramebuffer
                 && !(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE))
                 && surface_can_stretch_rect(Src, This))
         {
@@ -4342,6 +4350,7 @@ void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *co
 {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
     IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
 
     TRACE("(%p) New location %#x\n", This, location);
 
@@ -4373,7 +4382,7 @@ void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *co
 
             /* Note that we use depth_blt here as well, rather than glCopyTexImage2D
              * directly on the FBO texture. That's because we need to flip. */
-            context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL);
+            context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
             if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB)
             {
                 glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding);
@@ -4395,30 +4404,32 @@ void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *co
 
             /* Setup the destination */
             if (!device->depth_blt_rb) {
-                GL_EXTCALL(glGenRenderbuffersEXT(1, &device->depth_blt_rb));
+                gl_info->fbo_ops.glGenRenderbuffers(1, &device->depth_blt_rb);
                 checkGLcall("glGenRenderbuffersEXT");
             }
             if (device->depth_blt_rb_w != This->currentDesc.Width
                     || device->depth_blt_rb_h != This->currentDesc.Height) {
-                GL_EXTCALL(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, device->depth_blt_rb));
+                gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, device->depth_blt_rb);
                 checkGLcall("glBindRenderbufferEXT");
-                GL_EXTCALL(glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA8, This->currentDesc.Width, This->currentDesc.Height));
+                gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8,
+                        This->currentDesc.Width, This->currentDesc.Height);
                 checkGLcall("glRenderbufferStorageEXT");
                 device->depth_blt_rb_w = This->currentDesc.Width;
                 device->depth_blt_rb_h = This->currentDesc.Height;
             }
 
-            context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &context->dst_fbo);
-            GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, device->depth_blt_rb));
+            context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo);
+            gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+                    GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, device->depth_blt_rb);
             checkGLcall("glFramebufferRenderbufferEXT");
-            context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER_EXT, iface, FALSE);
+            context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, iface, FALSE);
 
             /* Do the actual blit */
             surface_depth_blt(This, device->depth_blt_texture, This->currentDesc.Width, This->currentDesc.Height, bind_target);
             checkGLcall("depth_blt");
 
-            if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &context->current_fbo->id);
-            else context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL);
+            if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER, &context->current_fbo->id);
+            else context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
 
             LEAVE_GL();
         } else {
@@ -4430,12 +4441,12 @@ void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *co
 
             ENTER_GL();
 
-            context_bind_fbo(context, GL_FRAMEBUFFER_EXT, NULL);
+            context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
             surface_depth_blt(This, This->texture_name, This->currentDesc.Width,
                     This->currentDesc.Height, This->texture_target);
             checkGLcall("depth_blt");
 
-            if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER_EXT, &context->current_fbo->id);
+            if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER, &context->current_fbo->id);
 
             LEAVE_GL();
         } else {
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 2d7a6b9..16755ef 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -443,6 +443,10 @@ static const GlPixelFormatDescTemplate gl_formats_template[] = {
             GL_DEPTH_STENCIL_EXT,   GL_UNSIGNED_INT_24_8_EXT,
             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
             EXT_PACKED_DEPTH_STENCIL},
+    {WINED3DFMT_D15S1,              GL_DEPTH24_STENCIL8,              GL_DEPTH24_STENCIL8,                    0,
+            GL_DEPTH_STENCIL,       GL_UNSIGNED_INT_24_8,
+            WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
+            ARB_FRAMEBUFFER_OBJECT},
     {WINED3DFMT_D24S8,              GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
             GL_DEPTH_COMPONENT,     GL_UNSIGNED_INT,
             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
@@ -451,6 +455,10 @@ static const GlPixelFormatDescTemplate gl_formats_template[] = {
             GL_DEPTH_STENCIL_EXT,   GL_UNSIGNED_INT_24_8_EXT,
             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
             EXT_PACKED_DEPTH_STENCIL},
+    {WINED3DFMT_D24S8,              GL_DEPTH24_STENCIL8,              GL_DEPTH24_STENCIL8,                    0,
+            GL_DEPTH_STENCIL,       GL_UNSIGNED_INT_24_8,
+            WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
+            ARB_FRAMEBUFFER_OBJECT},
     {WINED3DFMT_D24X8,              GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
             GL_DEPTH_COMPONENT,     GL_UNSIGNED_INT,
             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
@@ -463,6 +471,10 @@ static const GlPixelFormatDescTemplate gl_formats_template[] = {
             GL_DEPTH_STENCIL_EXT,   GL_UNSIGNED_INT_24_8_EXT,
             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
             EXT_PACKED_DEPTH_STENCIL},
+    {WINED3DFMT_D24X4S4,            GL_DEPTH24_STENCIL8,              GL_DEPTH24_STENCIL8,                    0,
+            GL_DEPTH_STENCIL,       GL_UNSIGNED_INT_24_8,
+            WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
+            ARB_FRAMEBUFFER_OBJECT},
     {WINED3DFMT_D16_UNORM,          GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
             GL_DEPTH_COMPONENT,     GL_UNSIGNED_SHORT,
             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
@@ -476,7 +488,7 @@ static const GlPixelFormatDescTemplate gl_formats_template[] = {
             WINED3DFMT_FLAG_DEPTH,
             ARB_DEPTH_BUFFER_FLOAT},
     {WINED3DFMT_D24FS8,             GL_DEPTH32F_STENCIL8,             GL_DEPTH32F_STENCIL8,                   0,
-            GL_DEPTH_STENCIL_EXT,   GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
+            GL_DEPTH_STENCIL,       GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
             ARB_DEPTH_BUFFER_FLOAT},
     /* Vendor-specific formats */
@@ -587,12 +599,12 @@ static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct GlPix
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
-    GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0));
+    gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
 
-    status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
+    status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
     checkGLcall("Framebuffer format check");
 
-    if (status == GL_FRAMEBUFFER_COMPLETE_EXT)
+    if (status == GL_FRAMEBUFFER_COMPLETE)
     {
         TRACE("Format %s is supported as FBO color attachment\n", debug_d3dformat(format_desc->format));
         format_desc->Flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
@@ -621,19 +633,19 @@ static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct GlPix
 
             while(glGetError());
 
-            GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, 0, 0));
+            gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
 
             glTexImage2D(GL_TEXTURE_2D, 0, format_desc->rtInternal, 16, 16, 0,
                     format_desc->glFormat, format_desc->glType, NULL);
             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
-            GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0));
+            gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
 
-            status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
+            status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
             checkGLcall("Framebuffer format check");
 
-            if (status == GL_FRAMEBUFFER_COMPLETE_EXT)
+            if (status == GL_FRAMEBUFFER_COMPLETE)
             {
                 TRACE("Format %s rtInternal format is supported as FBO color attachment\n",
                         debug_d3dformat(format_desc->format));
@@ -647,38 +659,36 @@ static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct GlPix
         }
     }
 
-    if (status == GL_FRAMEBUFFER_COMPLETE_EXT && format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
+    if (status == GL_FRAMEBUFFER_COMPLETE && format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
     {
         GLuint rb;
 
-        if (GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL))
+        if (GL_SUPPORT(ARB_FRAMEBUFFER_OBJECT)
+                || GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL))
         {
-            GL_EXTCALL(glGenRenderbuffersEXT(1, &rb));
-            GL_EXTCALL(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb));
-            GL_EXTCALL(glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, 16, 16));
-            GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
-                    GL_RENDERBUFFER_EXT, rb));
-            GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
-                    GL_RENDERBUFFER_EXT, rb));
+            gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
+            gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
+            gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
+            gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
+            gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
             checkGLcall("RB attachment");
         }
 
         glEnable(GL_BLEND);
         glClear(GL_COLOR_BUFFER_BIT);
-        if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION_EXT)
+        if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
         {
             while(glGetError());
             TRACE("Format doesn't support post-pixelshader blending.\n");
             format_desc->Flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
         }
 
-        if (GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL))
+        if (GL_SUPPORT(ARB_FRAMEBUFFER_OBJECT)
+                || GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL))
         {
-            GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
-                    GL_RENDERBUFFER_EXT, 0));
-            GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
-                    GL_RENDERBUFFER_EXT, 0));
-            GL_EXTCALL(glDeleteRenderbuffersEXT(1, &rb));
+            gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
+            gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
+            gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
             checkGLcall("RB cleanup");
         }
     }
@@ -698,8 +708,8 @@ static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
     {
         ENTER_GL();
 
-        GL_EXTCALL(glGenFramebuffersEXT(1, &fbo));
-        GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo));
+        gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
+        gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
 
         LEAVE_GL();
     }
@@ -739,7 +749,7 @@ static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
     {
         ENTER_GL();
 
-        GL_EXTCALL(glDeleteFramebuffersEXT(1, &fbo));
+        gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
 
         LEAVE_GL();
     }
@@ -830,10 +840,10 @@ static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
     glEnable(GL_TEXTURE_2D);
 
-    GL_EXTCALL(glGenFramebuffersEXT(1, &fbo));
-    GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo));
-    GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, buffer, 0));
-    glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
+    gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
+    gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+    gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
+    glDrawBuffer(GL_COLOR_ATTACHMENT0);
 
     glViewport(0, 0, 16, 1);
     glDisable(GL_LIGHTING);
@@ -873,8 +883,8 @@ static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
         ret = TRUE;
     }
 
-    GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
-    GL_EXTCALL(glDeleteFramebuffersEXT(1, &fbo));
+    gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
+    gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
     glDeleteTextures(1, &tex);
     glDeleteTextures(1, &buffer);
 
@@ -1762,15 +1772,16 @@ const char* debug_d3dpool(WINED3DPOOL Pool) {
 const char *debug_fbostatus(GLenum status) {
     switch(status) {
 #define FBOSTATUS_TO_STR(u) case u: return #u
-        FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE_EXT);
-        FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT);
-        FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
+        FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
+        FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
+        FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
-        FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT);
-        FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT);
-        FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT);
-        FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED_EXT);
+        FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
+        FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
+        FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
+        FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
+        FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
 #undef FBOSTATUS_TO_STR
         default:
             FIXME("Unrecognied FBO status 0x%08x\n", status);
@@ -1788,7 +1799,7 @@ const char *debug_glerror(GLenum error) {
         GLERROR_TO_STR(GL_STACK_OVERFLOW);
         GLERROR_TO_STR(GL_STACK_UNDERFLOW);
         GLERROR_TO_STR(GL_OUT_OF_MEMORY);
-        GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION_EXT);
+        GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
 #undef GLERROR_TO_STR
         default:
             FIXME("Unrecognied GL error 0x%08x\n", error);
diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h
index 03893ba..7c08f38 100644
--- a/dlls/wined3d/wined3d_gl.h
+++ b/dlls/wined3d/wined3d_gl.h
@@ -4097,6 +4097,29 @@ typedef BOOL (WINAPI * WINED3D_PFNWGLSETPIXELFORMATWINE) (HDC hdc, int iPixelFor
  * Structures
  ****************************************************/
 
+struct wined3d_fbo_ops
+{
+    PGLFNGLISRENDERBUFFERPROC                       glIsRenderbuffer;
+    PGLFNGLBINDRENDERBUFFERPROC                     glBindRenderbuffer;
+    PGLFNGLDELETERENDERBUFFERSPROC                  glDeleteRenderbuffers;
+    PGLFNGLGENRENDERBUFFERSPROC                     glGenRenderbuffers;
+    PGLFNGLRENDERBUFFERSTORAGEPROC                  glRenderbufferStorage;
+    PGLFNRENDERBUFFERSTORAGEMULTISAMPLEPROC         glRenderbufferStorageMultisample;
+    PGLFNGLGETRENDERBUFFERPARAMETERIVPROC           glGetRenderbufferParameteriv;
+    PGLFNGLISFRAMEBUFFERPROC                        glIsFramebuffer;
+    PGLFNGLBINDFRAMEBUFFERPROC                      glBindFramebuffer;
+    PGLFNGLDELETEFRAMEBUFFERSPROC                   glDeleteFramebuffers;
+    PGLFNGLGENFRAMEBUFFERSPROC                      glGenFramebuffers;
+    PGLFNGLCHECKFRAMEBUFFERSTATUSPROC               glCheckFramebufferStatus;
+    PGLFNGLFRAMEBUFFERTEXTURE1DPROC                 glFramebufferTexture1D;
+    PGLFNGLFRAMEBUFFERTEXTURE2DPROC                 glFramebufferTexture2D;
+    PGLFNGLFRAMEBUFFERTEXTURE3DPROC                 glFramebufferTexture3D;
+    PGLFNGLFRAMEBUFFERRENDERBUFFERPROC              glFramebufferRenderbuffer;
+    PGLFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC  glGetFramebufferAttachmentParameteriv;
+    PGLFNGLBLITFRAMEBUFFERPROC                      glBlitFramebuffer;
+    PGLFNGLGENERATEMIPMAPPROC                       glGenerateMipmap;
+};
+
 #define USE_GL_FUNC(type, pfn, ext, replace) type pfn;
 
 struct wined3d_gl_info
@@ -4145,6 +4168,7 @@ struct wined3d_gl_info
 
     BOOL supported[WINED3D_GL_EXT_COUNT];
 
+    struct wined3d_fbo_ops fbo_ops;
     /* GL function pointers */
     GL_EXT_FUNCS_GEN
     /* WGL function pointers */
-- 
1.6.0.6




More information about the wine-patches mailing list