From a269236649fb742f2e945eb8b0b58409dc070284 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Thu, 18 Sep 2008 14:57:53 +0200 Subject: [PATCH] wined3d: Move FBO handling functions to context.c. --- 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 088142ede4e..b6d8e9b10f5 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 1c05dc9ab98..496e5e84c3b 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 7b522f831c6..69bf0fb82d9 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 529d4bf0f43..654c585bf2b 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