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