Commit deeeda68 authored by H. Verbeet's avatar H. Verbeet Committed by Alexandre Julliard

wined3d: Properly handle the difference between GL_BACK and GL_FRONT for onscreen surfaces.

parent 5fddfd5b
...@@ -5280,23 +5280,24 @@ void apply_fbo_state(IWineD3DDevice *iface) { ...@@ -5280,23 +5280,24 @@ void apply_fbo_state(IWineD3DDevice *iface) {
check_fbo_status(iface); check_fbo_status(iface);
} }
static BOOL is_onscreen(IWineD3DSurface *target) { static IWineD3DSwapChain *get_swapchain(IWineD3DSurface *target) {
HRESULT hr; HRESULT hr;
void *tmp; IWineD3DSwapChain *swapchain;
hr = IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, &tmp); hr = IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, (void **)&swapchain);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
IWineD3DSwapChain_Release((IUnknown *)tmp); IWineD3DSwapChain_Release((IUnknown *)swapchain);
return TRUE; return swapchain;
} }
return FALSE; return NULL;
} }
void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, const WINED3DRECT *src_rect, 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) { IWineD3DSurface *dst_surface, const WINED3DRECT *dst_rect, const WINED3DTEXTUREFILTERTYPE filter, BOOL flip) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
GLbitfield mask = GL_COLOR_BUFFER_BIT; /* TODO: Support blitting depth/stencil surfaces */ GLbitfield mask = GL_COLOR_BUFFER_BIT; /* TODO: Support blitting depth/stencil surfaces */
IWineD3DSwapChain *src_swapchain, *dst_swapchain;
GLenum gl_filter; GLenum gl_filter;
TRACE("(%p) : src_surface %p, src_rect %p, dst_surface %p, dst_rect %p, filter %s (0x%08x), flip %u\n", 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 ...@@ -5321,25 +5322,45 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, const
} }
/* Attach src surface to src fbo */ /* 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); TRACE("Source surface %p is onscreen\n", src_surface);
GL_EXTCALL(glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0)); GL_EXTCALL(glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0));
buffer = surface_get_gl_buffer(src_surface, src_swapchain);
glReadBuffer(buffer);
checkGLcall("glReadBuffer()");
flip = !flip; flip = !flip;
} else { } else {
TRACE("Source surface %p is offscreen\n", src_surface); TRACE("Source surface %p is offscreen\n", src_surface);
bind_fbo(iface, GL_READ_FRAMEBUFFER_EXT, &This->src_fbo); bind_fbo(iface, GL_READ_FRAMEBUFFER_EXT, &This->src_fbo);
attach_surface_fbo(This, GL_READ_FRAMEBUFFER_EXT, 0, src_surface); attach_surface_fbo(This, GL_READ_FRAMEBUFFER_EXT, 0, src_surface);
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
checkGLcall("glReadBuffer()");
} }
/* Attach dst surface to dst fbo */ /* 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); TRACE("Destination surface %p is onscreen\n", dst_surface);
GL_EXTCALL(glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0)); GL_EXTCALL(glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0));
buffer = surface_get_gl_buffer(dst_surface, dst_swapchain);
glDrawBuffer(buffer);
checkGLcall("glDrawBuffer()");
flip = !flip; flip = !flip;
} else { } else {
TRACE("Destination surface %p is offscreen\n", dst_surface); TRACE("Destination surface %p is offscreen\n", dst_surface);
bind_fbo(iface, GL_DRAW_FRAMEBUFFER_EXT, &This->dst_fbo); bind_fbo(iface, GL_DRAW_FRAMEBUFFER_EXT, &This->dst_fbo);
attach_surface_fbo(This, GL_DRAW_FRAMEBUFFER_EXT, 0, dst_surface); attach_surface_fbo(This, GL_DRAW_FRAMEBUFFER_EXT, 0, dst_surface);
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
checkGLcall("glDrawBuffer()");
} }
if (flip) { if (flip) {
...@@ -5356,6 +5377,13 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, const ...@@ -5356,6 +5377,13 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, const
GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0)); GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
checkGLcall("glBindFramebuffer()"); 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) { static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderTarget(IWineD3DDevice *iface, DWORD RenderTargetIndex, IWineD3DSurface *pRenderTarget) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment