H. Verbeet : wined3d:
Properly handle the difference between GL_BACK and GL_FRONT for
onscreen surfaces .
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Apr 17 08:12:13 CDT 2007
Module: wine
Branch: master
Commit: deeeda6802bc3fbca599ad287c5fcfd69172a525
URL: http://source.winehq.org/git/wine.git/?a=commit;h=deeeda6802bc3fbca599ad287c5fcfd69172a525
Author: H. Verbeet <hverbeet at gmail.com>
Date: Mon Apr 16 21:20:56 2007 +0200
wined3d: Properly handle the difference between GL_BACK and GL_FRONT for onscreen surfaces.
---
dlls/wined3d/device.c | 44 ++++++++++++++++++++++++++++++++++++--------
1 files changed, 36 insertions(+), 8 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 2fe9c0e..1e3d18a 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -5280,23 +5280,24 @@ void apply_fbo_state(IWineD3DDevice *iface) {
check_fbo_status(iface);
}
-static BOOL is_onscreen(IWineD3DSurface *target) {
+static IWineD3DSwapChain *get_swapchain(IWineD3DSurface *target) {
HRESULT hr;
- void *tmp;
+ IWineD3DSwapChain *swapchain;
- hr = IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, &tmp);
+ hr = IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, (void **)&swapchain);
if (SUCCEEDED(hr)) {
- IWineD3DSwapChain_Release((IUnknown *)tmp);
- return TRUE;
+ IWineD3DSwapChain_Release((IUnknown *)swapchain);
+ return swapchain;
}
- return FALSE;
+ return NULL;
}
void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, const WINED3DRECT *src_rect,
IWineD3DSurface *dst_surface, const WINED3DRECT *dst_rect, const WINED3DTEXTUREFILTERTYPE filter, BOOL flip) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
GLbitfield mask = GL_COLOR_BUFFER_BIT; /* TODO: Support blitting depth/stencil surfaces */
+ IWineD3DSwapChain *src_swapchain, *dst_swapchain;
GLenum gl_filter;
TRACE("(%p) : src_surface %p, src_rect %p, dst_surface %p, dst_rect %p, filter %s (0x%08x), flip %u\n",
@@ -5321,25 +5322,45 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, const
}
/* Attach src surface to src fbo */
- if (is_onscreen(src_surface)) {
+ src_swapchain = get_swapchain(src_surface);
+ if (src_swapchain) {
+ GLenum buffer;
+
TRACE("Source surface %p is onscreen\n", src_surface);
+
GL_EXTCALL(glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0));
+ buffer = surface_get_gl_buffer(src_surface, src_swapchain);
+ glReadBuffer(buffer);
+ checkGLcall("glReadBuffer()");
+
flip = !flip;
} else {
TRACE("Source surface %p is offscreen\n", src_surface);
bind_fbo(iface, GL_READ_FRAMEBUFFER_EXT, &This->src_fbo);
attach_surface_fbo(This, GL_READ_FRAMEBUFFER_EXT, 0, src_surface);
+ glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
+ checkGLcall("glReadBuffer()");
}
/* Attach dst surface to dst fbo */
- if (is_onscreen(dst_surface)) {
+ dst_swapchain = get_swapchain(dst_surface);
+ if (dst_swapchain) {
+ GLenum buffer;
+
TRACE("Destination surface %p is onscreen\n", dst_surface);
+
GL_EXTCALL(glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0));
+ buffer = surface_get_gl_buffer(dst_surface, dst_swapchain);
+ glDrawBuffer(buffer);
+ checkGLcall("glDrawBuffer()");
+
flip = !flip;
} else {
TRACE("Destination surface %p is offscreen\n", dst_surface);
bind_fbo(iface, GL_DRAW_FRAMEBUFFER_EXT, &This->dst_fbo);
attach_surface_fbo(This, GL_DRAW_FRAMEBUFFER_EXT, 0, dst_surface);
+ glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
+ checkGLcall("glDrawBuffer()");
}
if (flip) {
@@ -5356,6 +5377,13 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, const
GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
checkGLcall("glBindFramebuffer()");
}
+
+ /* If we switched from GL_BACK to GL_FRONT above, we need to switch back here */
+ if (dst_swapchain && dst_surface == ((IWineD3DSwapChainImpl *)dst_swapchain)->frontBuffer
+ && ((IWineD3DSwapChainImpl *)dst_swapchain)->backBuffer) {
+ glDrawBuffer(GL_BACK);
+ checkGLcall("glDrawBuffer()");
+ }
}
static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderTarget(IWineD3DDevice *iface, DWORD RenderTargetIndex, IWineD3DSurface *pRenderTarget) {
More information about the wine-cvs
mailing list