wined3d: Move FBO handling functions to context.c

Henri Verbeet hverbeet at codeweavers.com
Thu Sep 18 07:57:53 CDT 2008


Considering the context is responsible for FBOs these days, this seems
appropriate.
---
 dlls/wined3d/context.c         |  293 ++++++++++++++++++++++++++++++++++++----
 dlls/wined3d/device.c          |  228 +------------------------------
 dlls/wined3d/surface.c         |    6 +-
 dlls/wined3d/wined3d_private.h |    7 +-
 4 files changed, 282 insertions(+), 252 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 088142e..b6d8e9b 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -36,6 +36,268 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d);
  */
 static IWineD3DDeviceImpl *last_device;
 
+/* FBO helper functions */
+
+void context_bind_fbo(IWineD3DDevice *iface, GLenum target, GLuint *fbo)
+{
+    const IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+
+    if (!*fbo)
+    {
+        GL_EXTCALL(glGenFramebuffersEXT(1, fbo));
+        checkGLcall("glGenFramebuffersEXT()");
+        TRACE("Created FBO %d\n", *fbo);
+    }
+
+    GL_EXTCALL(glBindFramebufferEXT(target, *fbo));
+    checkGLcall("glBindFramebuffer()");
+}
+
+static void context_destroy_fbo(IWineD3DDeviceImpl *This, const GLuint *fbo)
+{
+    int i = 0;
+
+    GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, *fbo));
+    checkGLcall("glBindFramebuffer()");
+    for (i = 0; i < GL_LIMITS(buffers); ++i)
+    {
+        GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + i, GL_TEXTURE_2D, 0, 0));
+        checkGLcall("glFramebufferTexture2D()");
+    }
+    GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
+    checkGLcall("glFramebufferTexture2D()");
+    GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
+    checkGLcall("glBindFramebuffer()");
+    GL_EXTCALL(glDeleteFramebuffersEXT(1, fbo));
+    checkGLcall("glDeleteFramebuffers()");
+}
+
+/* TODO: Handle stencil attachments */
+void context_attach_depth_stencil_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, IWineD3DSurface *depth_stencil, BOOL use_render_buffer)
+{
+    IWineD3DSurfaceImpl *depth_stencil_impl = (IWineD3DSurfaceImpl *)depth_stencil;
+
+    if (use_render_buffer && depth_stencil_impl->current_renderbuffer)
+    {
+        GL_EXTCALL(glFramebufferRenderbufferEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_stencil_impl->current_renderbuffer->id));
+        checkGLcall("glFramebufferRenderbufferEXT()");
+    } else {
+        IWineD3DBaseTextureImpl *texture_impl;
+        GLenum texttarget, target;
+        GLint old_binding = 0;
+
+        texttarget = depth_stencil_impl->glDescription.target;
+        if (texttarget == GL_TEXTURE_2D)
+        {
+            target = GL_TEXTURE_2D;
+            glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding);
+        } else if (texttarget == GL_TEXTURE_RECTANGLE_ARB) {
+            target = GL_TEXTURE_RECTANGLE_ARB;
+            glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding);
+        } else {
+            target = GL_TEXTURE_CUBE_MAP_ARB;
+            glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP_ARB, &old_binding);
+        }
+
+        IWineD3DSurface_PreLoad(depth_stencil);
+
+        glBindTexture(target, depth_stencil_impl->glDescription.textureName);
+        glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+        glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        glTexParameteri(target, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
+        glBindTexture(target, old_binding);
+
+        /* Update base texture states array */
+        if (SUCCEEDED(IWineD3DSurface_GetContainer(depth_stencil, &IID_IWineD3DBaseTexture, (void **)&texture_impl)))
+        {
+            texture_impl->baseTexture.states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT;
+            texture_impl->baseTexture.states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_POINT;
+            if (texture_impl->baseTexture.bindCount)
+            {
+                IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(texture_impl->baseTexture.sampler));
+            }
+
+            IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture_impl);
+        }
+
+        GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT, texttarget,
+                    depth_stencil_impl->glDescription.textureName, depth_stencil_impl->glDescription.level));
+        checkGLcall("glFramebufferTexture2DEXT()");
+    }
+}
+
+void context_attach_surface_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, DWORD idx, IWineD3DSurface *surface)
+{
+    const IWineD3DSurfaceImpl *surface_impl = (IWineD3DSurfaceImpl *)surface;
+    IWineD3DBaseTextureImpl *texture_impl;
+    GLenum texttarget, target;
+    GLint old_binding;
+
+    texttarget = surface_impl->glDescription.target;
+    if (texttarget == GL_TEXTURE_2D)
+    {
+        target = GL_TEXTURE_2D;
+        glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding);
+    } else if (texttarget == GL_TEXTURE_RECTANGLE_ARB) {
+        target = GL_TEXTURE_RECTANGLE_ARB;
+        glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding);
+    } else {
+        target = GL_TEXTURE_CUBE_MAP_ARB;
+        glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP_ARB, &old_binding);
+    }
+
+    IWineD3DSurface_PreLoad(surface);
+
+    glBindTexture(target, surface_impl->glDescription.textureName);
+    glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glBindTexture(target, old_binding);
+
+    /* Update base texture states array */
+    if (SUCCEEDED(IWineD3DSurface_GetContainer(surface, &IID_IWineD3DBaseTexture, (void **)&texture_impl)))
+    {
+        texture_impl->baseTexture.states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT;
+        texture_impl->baseTexture.states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_POINT;
+        if (texture_impl->baseTexture.bindCount)
+        {
+            IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(texture_impl->baseTexture.sampler));
+        }
+
+        IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture_impl);
+    }
+
+    GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_COLOR_ATTACHMENT0_EXT + idx, texttarget,
+            surface_impl->glDescription.textureName, surface_impl->glDescription.level));
+
+    checkGLcall("attach_surface_fbo");
+}
+
+/* TODO: Handle stencil attachments */
+static void context_set_depth_stencil_fbo(IWineD3DDevice *iface, IWineD3DSurface *depth_stencil)
+{
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+
+    TRACE("Set depth stencil to %p\n", depth_stencil);
+
+    if (depth_stencil)
+    {
+        context_attach_depth_stencil_fbo(This, GL_FRAMEBUFFER_EXT, depth_stencil, TRUE);
+    } else {
+        GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
+        checkGLcall("glFramebufferTexture2DEXT()");
+    }
+}
+
+static void context_set_render_target_fbo(IWineD3DDevice *iface, DWORD idx, IWineD3DSurface *render_target)
+{
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+
+    TRACE("Set render target %u to %p\n", idx, render_target);
+
+    if (render_target)
+    {
+        context_attach_surface_fbo(This, GL_FRAMEBUFFER_EXT, idx, render_target);
+        This->draw_buffers[idx] = GL_COLOR_ATTACHMENT0_EXT + idx;
+    } else {
+        GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + idx, GL_TEXTURE_2D, 0, 0));
+        checkGLcall("glFramebufferTexture2DEXT()");
+
+        This->draw_buffers[idx] = GL_NONE;
+    }
+}
+
+static void context_check_fbo_status(IWineD3DDevice *iface)
+{
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    GLenum status;
+
+    status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
+    if (status == GL_FRAMEBUFFER_COMPLETE_EXT)
+    {
+        TRACE("FBO complete\n");
+    } else {
+        IWineD3DSurfaceImpl *attachment;
+        int i;
+        FIXME("FBO status %s (%#x)\n", debug_fbostatus(status), status);
+
+        /* Dump the FBO attachments */
+        for (i = 0; i < GL_LIMITS(buffers); ++i)
+        {
+            attachment = (IWineD3DSurfaceImpl *)This->activeContext->fbo_color_attachments[i];
+            if (attachment)
+            {
+                FIXME("\tColor attachment %d: (%p) %s %ux%u\n", i, attachment, debug_d3dformat(attachment->resource.format),
+                        attachment->pow2Width, attachment->pow2Height);
+            }
+        }
+        attachment = (IWineD3DSurfaceImpl *)This->activeContext->fbo_depth_attachment;
+        if (attachment)
+        {
+            FIXME("\tDepth attachment: (%p) %s %ux%u\n", attachment, debug_d3dformat(attachment->resource.format),
+                    attachment->pow2Width, attachment->pow2Height);
+        }
+    }
+}
+
+static BOOL context_depth_mismatch_fbo(IWineD3DDevice *iface)
+{
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    IWineD3DSurfaceImpl *rt_impl = (IWineD3DSurfaceImpl *)This->render_targets[0];
+    IWineD3DSurfaceImpl *ds_impl = (IWineD3DSurfaceImpl *)This->stencilBufferTarget;
+
+    if (!ds_impl) return FALSE;
+
+    if (ds_impl->current_renderbuffer)
+    {
+        return (rt_impl->pow2Width != ds_impl->current_renderbuffer->width ||
+                rt_impl->pow2Height != ds_impl->current_renderbuffer->height);
+    }
+
+    return (rt_impl->pow2Width != ds_impl->pow2Width ||
+            rt_impl->pow2Height != ds_impl->pow2Height);
+}
+
+void context_apply_fbo_state(IWineD3DDevice *iface)
+{
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    WineD3DContext *context = This->activeContext;
+    unsigned int i;
+
+    if (This->render_offscreen)
+    {
+        context_bind_fbo(iface, GL_FRAMEBUFFER_EXT, &context->fbo);
+
+        /* Apply render targets */
+        for (i = 0; i < GL_LIMITS(buffers); ++i)
+        {
+            IWineD3DSurface *render_target = This->render_targets[i];
+            if (context->fbo_color_attachments[i] != render_target)
+            {
+                context_set_render_target_fbo(iface, i, render_target);
+                context->fbo_color_attachments[i] = render_target;
+            }
+        }
+
+        /* Apply depth targets */
+        if (context->fbo_depth_attachment != This->stencilBufferTarget || context_depth_mismatch_fbo(iface))
+        {
+            unsigned int w = ((IWineD3DSurfaceImpl *)This->render_targets[0])->pow2Width;
+            unsigned int h = ((IWineD3DSurfaceImpl *)This->render_targets[0])->pow2Height;
+
+            if (This->stencilBufferTarget)
+            {
+                surface_set_compatible_renderbuffer(This->stencilBufferTarget, w, h);
+            }
+            context_set_depth_stencil_fbo(iface, This->stencilBufferTarget);
+            context->fbo_depth_attachment = This->stencilBufferTarget;
+        }
+    } else {
+        GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
+    }
+
+    context_check_fbo_status(iface);
+}
+
 /*****************************************************************************
  * Context_MarkStateDirty
  *
@@ -632,25 +894,6 @@ static void RemoveContextFromArray(IWineD3DDeviceImpl *This, WineD3DContext *con
     HeapFree(GetProcessHeap(), 0, oldArray);
 }
 
-static void destroy_fbo(IWineD3DDeviceImpl *This, const GLuint *fbo)
-{
-    int i = 0;
-
-    GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, *fbo));
-    checkGLcall("glBindFramebuffer()");
-    for (i = 0; i < GL_LIMITS(buffers); ++i)
-    {
-        GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + i, GL_TEXTURE_2D, 0, 0));
-        checkGLcall("glFramebufferTexture2D()");
-    }
-    GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
-    checkGLcall("glFramebufferTexture2D()");
-    GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
-    checkGLcall("glBindFramebuffer()");
-    GL_EXTCALL(glDeleteFramebuffersEXT(1, fbo));
-    checkGLcall("glDeleteFramebuffers()");
-}
-
 /*****************************************************************************
  * DestroyContext
  *
@@ -675,15 +918,15 @@ void DestroyContext(IWineD3DDeviceImpl *This, WineD3DContext *context) {
 
     if (context->fbo) {
         TRACE("Destroy FBO %d\n", context->fbo);
-        destroy_fbo(This, &context->fbo);
+        context_destroy_fbo(This, &context->fbo);
     }
     if (context->src_fbo) {
         TRACE("Destroy src FBO %d\n", context->src_fbo);
-        destroy_fbo(This, &context->src_fbo);
+        context_destroy_fbo(This, &context->src_fbo);
     }
     if (context->dst_fbo) {
         TRACE("Destroy dst FBO %d\n", context->dst_fbo);
-        destroy_fbo(This, &context->dst_fbo);
+        context_destroy_fbo(This, &context->dst_fbo);
     }
 
     LEAVE_GL();
@@ -1225,7 +1468,7 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
         case CTXUSAGE_CLEAR:
         case CTXUSAGE_DRAWPRIM:
             if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
-                apply_fbo_state((IWineD3DDevice *)This);
+                context_apply_fbo_state((IWineD3DDevice *)This);
             }
             if (context->draw_buffer_dirty) {
                 apply_draw_buffer(This, target, FALSE);
@@ -1237,8 +1480,8 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
             if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
                 if (This->render_offscreen) {
                     FIXME("Activating for CTXUSAGE_BLIT for an offscreen target with ORM_FBO. This should be avoided.\n");
-                    bind_fbo((IWineD3DDevice *)This, GL_FRAMEBUFFER_EXT, &context->dst_fbo);
-                    attach_surface_fbo(This, GL_FRAMEBUFFER_EXT, 0, target);
+                    context_bind_fbo((IWineD3DDevice *)This, GL_FRAMEBUFFER_EXT, &context->dst_fbo);
+                    context_attach_surface_fbo(This, GL_FRAMEBUFFER_EXT, 0, target);
                     GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0));
                     checkGLcall("glFramebufferRenderbufferEXT");
                 } else {
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 1c05dc9..496e5e8 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -6122,109 +6122,6 @@ static IWineD3DSwapChain *get_swapchain(IWineD3DSurface *target) {
     return NULL;
 }
 
-void bind_fbo(IWineD3DDevice *iface, GLenum target, GLuint *fbo) {
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-
-    if (!*fbo) {
-        GL_EXTCALL(glGenFramebuffersEXT(1, fbo));
-        checkGLcall("glGenFramebuffersEXT()");
-        TRACE("Created FBO %d\n", *fbo);
-    }
-    GL_EXTCALL(glBindFramebufferEXT(target, *fbo));
-    checkGLcall("glBindFramebuffer()");
-}
-
-/* TODO: Handle stencil attachments */
-void attach_depth_stencil_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, IWineD3DSurface *depth_stencil, BOOL use_render_buffer) {
-    IWineD3DSurfaceImpl *depth_stencil_impl = (IWineD3DSurfaceImpl *)depth_stencil;
-
-    if (use_render_buffer && depth_stencil_impl->current_renderbuffer) {
-        GL_EXTCALL(glFramebufferRenderbufferEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_stencil_impl->current_renderbuffer->id));
-        checkGLcall("glFramebufferRenderbufferEXT()");
-    } else {
-        IWineD3DBaseTextureImpl *texture_impl;
-        GLenum texttarget, target;
-        GLint old_binding = 0;
-
-        texttarget = depth_stencil_impl->glDescription.target;
-        if(texttarget == GL_TEXTURE_2D) {
-            target = GL_TEXTURE_2D;
-            glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding);
-        } else if(texttarget == GL_TEXTURE_RECTANGLE_ARB) {
-            target = GL_TEXTURE_RECTANGLE_ARB;
-            glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding);
-        } else {
-            target = GL_TEXTURE_CUBE_MAP_ARB;
-            glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP_ARB, &old_binding);
-        }
-
-        IWineD3DSurface_PreLoad(depth_stencil);
-
-        glBindTexture(target, depth_stencil_impl->glDescription.textureName);
-        glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-        glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-        glTexParameteri(target, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
-        glBindTexture(target, old_binding);
-
-        /* Update base texture states array */
-        if (SUCCEEDED(IWineD3DSurface_GetContainer(depth_stencil, &IID_IWineD3DBaseTexture, (void **)&texture_impl))) {
-            texture_impl->baseTexture.states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT;
-            texture_impl->baseTexture.states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_POINT;
-            if (texture_impl->baseTexture.bindCount) {
-                IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(texture_impl->baseTexture.sampler));
-            }
-
-            IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture_impl);
-        }
-
-        GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_DEPTH_ATTACHMENT_EXT, texttarget,
-                    depth_stencil_impl->glDescription.textureName, depth_stencil_impl->glDescription.level));
-        checkGLcall("glFramebufferTexture2DEXT()");
-    }
-}
-
-void attach_surface_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, DWORD idx, IWineD3DSurface *surface) {
-    const IWineD3DSurfaceImpl *surface_impl = (IWineD3DSurfaceImpl *)surface;
-    IWineD3DBaseTextureImpl *texture_impl;
-    GLenum texttarget, target;
-    GLint old_binding;
-
-    texttarget = surface_impl->glDescription.target;
-    if(texttarget == GL_TEXTURE_2D) {
-        target = GL_TEXTURE_2D;
-        glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding);
-    } else if(texttarget == GL_TEXTURE_RECTANGLE_ARB) {
-        target = GL_TEXTURE_RECTANGLE_ARB;
-        glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding);
-    } else {
-        target = GL_TEXTURE_CUBE_MAP_ARB;
-        glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP_ARB, &old_binding);
-    }
-
-    IWineD3DSurface_PreLoad(surface);
-
-    glBindTexture(target, surface_impl->glDescription.textureName);
-    glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    glBindTexture(target, old_binding);
-
-    /* Update base texture states array */
-    if (SUCCEEDED(IWineD3DSurface_GetContainer(surface, &IID_IWineD3DBaseTexture, (void **)&texture_impl))) {
-        texture_impl->baseTexture.states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT;
-        texture_impl->baseTexture.states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_POINT;
-        if (texture_impl->baseTexture.bindCount) {
-            IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(texture_impl->baseTexture.sampler));
-        }
-
-        IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture_impl);
-    }
-
-    GL_EXTCALL(glFramebufferTexture2DEXT(fbo_target, GL_COLOR_ATTACHMENT0_EXT + idx, texttarget,
-            surface_impl->glDescription.textureName, surface_impl->glDescription.level));
-
-    checkGLcall("attach_surface_fbo");
-}
-
 static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface, CONST WINED3DRECT *rect, WINED3DCOLOR color) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
     IWineD3DSwapChain *swapchain;
@@ -6246,8 +6143,8 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface, CONS
 
         ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
         ENTER_GL();
-        bind_fbo(iface, GL_FRAMEBUFFER_EXT, &This->activeContext->dst_fbo);
-        attach_surface_fbo(This, GL_FRAMEBUFFER_EXT, 0, surface);
+        context_bind_fbo(iface, GL_FRAMEBUFFER_EXT, &This->activeContext->dst_fbo);
+        context_attach_surface_fbo(This, GL_FRAMEBUFFER_EXT, 0, surface);
         GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0));
         checkGLcall("glFramebufferRenderbufferEXT");
     }
@@ -6278,7 +6175,7 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface, CONS
     checkGLcall("glClear");
 
     if (This->render_offscreen) {
-        bind_fbo(iface, GL_FRAMEBUFFER_EXT, &This->activeContext->fbo);
+        context_bind_fbo(iface, GL_FRAMEBUFFER_EXT, &This->activeContext->fbo);
     } else {
         GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
         checkGLcall("glBindFramebuffer()");
@@ -6542,115 +6439,6 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_GetDepthStencilSurface(IWineD3DDevice
     }
 }
 
-/* TODO: Handle stencil attachments */
-static void set_depth_stencil_fbo(IWineD3DDevice *iface, IWineD3DSurface *depth_stencil) {
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-
-    TRACE("Set depth stencil to %p\n", depth_stencil);
-
-    if (depth_stencil) {
-        attach_depth_stencil_fbo(This, GL_FRAMEBUFFER_EXT, depth_stencil, TRUE);
-    } else {
-        GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0));
-        checkGLcall("glFramebufferTexture2DEXT()");
-    }
-}
-
-static void set_render_target_fbo(IWineD3DDevice *iface, DWORD idx, IWineD3DSurface *render_target) {
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-
-    TRACE("Set render target %u to %p\n", idx, render_target);
-
-    if (render_target) {
-        attach_surface_fbo(This, GL_FRAMEBUFFER_EXT, idx, render_target);
-        This->draw_buffers[idx] = GL_COLOR_ATTACHMENT0_EXT + idx;
-    } else {
-        GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + idx, GL_TEXTURE_2D, 0, 0));
-        checkGLcall("glFramebufferTexture2DEXT()");
-
-        This->draw_buffers[idx] = GL_NONE;
-    }
-}
-
-static void check_fbo_status(IWineD3DDevice *iface) {
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    GLenum status;
-
-    status = GL_EXTCALL(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
-    if (status == GL_FRAMEBUFFER_COMPLETE_EXT) {
-        TRACE("FBO complete\n");
-    } else {
-        IWineD3DSurfaceImpl *attachment;
-        int i;
-        FIXME("FBO status %s (%#x)\n", debug_fbostatus(status), status);
-
-        /* Dump the FBO attachments */
-        for (i = 0; i < GL_LIMITS(buffers); ++i) {
-            attachment = (IWineD3DSurfaceImpl *)This->activeContext->fbo_color_attachments[i];
-            if (attachment) {
-                FIXME("\tColor attachment %d: (%p) %s %ux%u\n", i, attachment, debug_d3dformat(attachment->resource.format),
-                        attachment->pow2Width, attachment->pow2Height);
-            }
-        }
-        attachment = (IWineD3DSurfaceImpl *)This->activeContext->fbo_depth_attachment;
-        if (attachment) {
-            FIXME("\tDepth attachment: (%p) %s %ux%u\n", attachment, debug_d3dformat(attachment->resource.format),
-                    attachment->pow2Width, attachment->pow2Height);
-        }
-    }
-}
-
-static BOOL depth_mismatch_fbo(IWineD3DDevice *iface) {
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    IWineD3DSurfaceImpl *rt_impl = (IWineD3DSurfaceImpl *)This->render_targets[0];
-    IWineD3DSurfaceImpl *ds_impl = (IWineD3DSurfaceImpl *)This->stencilBufferTarget;
-
-    if (!ds_impl) return FALSE;
-
-    if (ds_impl->current_renderbuffer) {
-        return (rt_impl->pow2Width != ds_impl->current_renderbuffer->width ||
-                rt_impl->pow2Height != ds_impl->current_renderbuffer->height);
-    }
-
-    return (rt_impl->pow2Width != ds_impl->pow2Width ||
-            rt_impl->pow2Height != ds_impl->pow2Height);
-}
-
-void apply_fbo_state(IWineD3DDevice *iface) {
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    WineD3DContext *context = This->activeContext;
-    unsigned int i;
-
-    if (This->render_offscreen) {
-        bind_fbo(iface, GL_FRAMEBUFFER_EXT, &context->fbo);
-
-        /* Apply render targets */
-        for (i = 0; i < GL_LIMITS(buffers); ++i) {
-            IWineD3DSurface *render_target = This->render_targets[i];
-            if (context->fbo_color_attachments[i] != render_target) {
-                set_render_target_fbo(iface, i, render_target);
-                context->fbo_color_attachments[i] = render_target;
-            }
-        }
-
-        /* Apply depth targets */
-        if (context->fbo_depth_attachment != This->stencilBufferTarget || depth_mismatch_fbo(iface)) {
-            unsigned int w = ((IWineD3DSurfaceImpl *)This->render_targets[0])->pow2Width;
-            unsigned int h = ((IWineD3DSurfaceImpl *)This->render_targets[0])->pow2Height;
-
-            if (This->stencilBufferTarget) {
-                surface_set_compatible_renderbuffer(This->stencilBufferTarget, w, h);
-            }
-            set_depth_stencil_fbo(iface, This->stencilBufferTarget);
-            context->fbo_depth_attachment = This->stencilBufferTarget;
-        }
-    } else {
-        GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
-    }
-
-    check_fbo_status(iface);
-}
-
 void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED3DRECT *src_rect,
         IWineD3DSurface *dst_surface, WINED3DRECT *dst_rect, const WINED3DTEXTUREFILTERTYPE filter, BOOL flip) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
@@ -6709,8 +6497,8 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
     } else {
         TRACE("Source surface %p is offscreen\n", src_surface);
         ENTER_GL();
-        bind_fbo(iface, GL_READ_FRAMEBUFFER_EXT, &This->activeContext->src_fbo);
-        attach_surface_fbo(This, GL_READ_FRAMEBUFFER_EXT, 0, src_surface);
+        context_bind_fbo(iface, GL_READ_FRAMEBUFFER_EXT, &This->activeContext->src_fbo);
+        context_attach_surface_fbo(This, GL_READ_FRAMEBUFFER_EXT, 0, src_surface);
         glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
         checkGLcall("glReadBuffer()");
         GL_EXTCALL(glFramebufferRenderbufferEXT(GL_READ_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0));
@@ -6757,8 +6545,8 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
         }
 
         ENTER_GL();
-        bind_fbo(iface, GL_DRAW_FRAMEBUFFER_EXT, &This->activeContext->dst_fbo);
-        attach_surface_fbo(This, GL_DRAW_FRAMEBUFFER_EXT, 0, dst_surface);
+        context_bind_fbo(iface, GL_DRAW_FRAMEBUFFER_EXT, &This->activeContext->dst_fbo);
+        context_attach_surface_fbo(This, GL_DRAW_FRAMEBUFFER_EXT, 0, dst_surface);
         glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
         checkGLcall("glDrawBuffer()");
         GL_EXTCALL(glFramebufferRenderbufferEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0));
@@ -6780,7 +6568,7 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
     IWineD3DSurface_ModifyLocation(dst_surface, SFLAG_INDRAWABLE, TRUE);
 
     if (This->render_offscreen) {
-        bind_fbo(iface, GL_FRAMEBUFFER_EXT, &This->activeContext->fbo);
+        context_bind_fbo(iface, GL_FRAMEBUFFER_EXT, &This->activeContext->fbo);
     } else {
         GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
         checkGLcall("glBindFramebuffer()");
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 7b522f8..69bf0fb 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -3995,17 +3995,17 @@ void surface_load_ds_location(IWineD3DSurface *iface, DWORD location) {
                 device->depth_blt_rb_h = This->currentDesc.Height;
             }
 
-            bind_fbo((IWineD3DDevice *)device, GL_FRAMEBUFFER_EXT, &device->activeContext->dst_fbo);
+            context_bind_fbo((IWineD3DDevice *)device, GL_FRAMEBUFFER_EXT, &device->activeContext->dst_fbo);
             GL_EXTCALL(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, device->depth_blt_rb));
             checkGLcall("glFramebufferRenderbufferEXT");
-            attach_depth_stencil_fbo(device, GL_FRAMEBUFFER_EXT, iface, FALSE);
+            context_attach_depth_stencil_fbo(device, GL_FRAMEBUFFER_EXT, iface, FALSE);
 
             /* Do the actual blit */
             depth_blt((IWineD3DDevice *)device, device->depth_blt_texture, This->currentDesc.Width, This->currentDesc.Height);
             checkGLcall("depth_blt");
 
             if (device->render_offscreen) {
-                bind_fbo((IWineD3DDevice *)device, GL_FRAMEBUFFER_EXT, &device->activeContext->fbo);
+                context_bind_fbo((IWineD3DDevice *)device, GL_FRAMEBUFFER_EXT, &device->activeContext->fbo);
             } else {
                 GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
                 checkGLcall("glBindFramebuffer()");
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 529d4bf..654c585 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -630,7 +630,9 @@ typedef enum ContextUsage {
 void ActivateContext(IWineD3DDeviceImpl *device, IWineD3DSurface *target, ContextUsage usage);
 WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, HWND win, BOOL create_pbuffer, const WINED3DPRESENT_PARAMETERS *pPresentParms);
 void DestroyContext(IWineD3DDeviceImpl *This, WineD3DContext *context);
-void apply_fbo_state(IWineD3DDevice *iface);
+void context_bind_fbo(IWineD3DDevice *iface, GLenum target, GLuint *fbo);
+void context_attach_depth_stencil_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, IWineD3DSurface *depth_stencil, BOOL use_render_buffer);
+void context_attach_surface_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, DWORD idx, IWineD3DSurface *surface);
 
 void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain);
 HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain);
@@ -2431,9 +2433,6 @@ static inline BOOL use_ps(IWineD3DDeviceImpl *device) {
 
 void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED3DRECT *src_rect,
         IWineD3DSurface *dst_surface, WINED3DRECT *dst_rect, const WINED3DTEXTUREFILTERTYPE filter, BOOL flip);
-void bind_fbo(IWineD3DDevice *iface, GLenum target, GLuint *fbo);
-void attach_depth_stencil_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, IWineD3DSurface *depth_stencil, BOOL use_render_buffer);
-void attach_surface_fbo(IWineD3DDeviceImpl *This, GLenum fbo_target, DWORD idx, IWineD3DSurface *surface);
 void depth_blt(IWineD3DDevice *iface, GLuint texture, GLsizei w, GLsizei h);
 
 #endif
-- 
1.5.6.4



--------------080200070008030603080601--



More information about the wine-patches mailing list