diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 6775a61b9b9..1eaf9529267 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -4942,13 +4942,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Clear(IWineD3DDevice *iface, DWORD Coun IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *)This->render_targets[0]; - GLbitfield glMask = 0; - unsigned int i; - WINED3DRECT curRect; - RECT vp_rect; - WINED3DVIEWPORT *vp = &This->stateBlock->viewport; - UINT drawable_width, drawable_height; - TRACE("(%p) Count (%d), pRects (%p), Flags (%x), Color (0x%08x), Z (%f), Stencil (%d)\n", This, Count, pRects, Flags, Color, Z, Stencil); @@ -4958,158 +4951,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Clear(IWineD3DDevice *iface, DWORD Coun return WINED3DERR_INVALIDCALL; } - /* When we're clearing parts of the drawable, make sure that the target surface is well up to date in the - * drawable. After the clear we'll mark the drawable up to date, so we have to make sure that this is true - * for the cleared parts, and the untouched parts. - * - * If we're clearing the whole target there is no need to copy it into the drawable, it will be overwritten - * anyway. If we're not clearing the color buffer we don't have to copy either since we're not going to set - * the drawable up to date. We have to check all settings that limit the clear area though. Do not bother - * checking all this if the dest surface is in the drawable anyway. - */ - if((Flags & WINED3DCLEAR_TARGET) && !(target->Flags & SFLAG_INDRAWABLE)) { - while(1) { - if(vp->X != 0 || vp->Y != 0 || - vp->Width < target->currentDesc.Width || vp->Height < target->currentDesc.Height) { - IWineD3DSurface_LoadLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, NULL); - break; - } - if(This->stateBlock->renderState[WINED3DRS_SCISSORTESTENABLE] && ( - This->stateBlock->scissorRect.left > 0 || This->stateBlock->scissorRect.top > 0 || - This->stateBlock->scissorRect.right < target->currentDesc.Width || - This->stateBlock->scissorRect.bottom < target->currentDesc.Height)) { - IWineD3DSurface_LoadLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, NULL); - break; - } - if(Count > 0 && pRects && ( - pRects[0].x1 > 0 || pRects[0].y1 > 0 || - pRects[0].x2 < target->currentDesc.Width || - pRects[0].y2 < target->currentDesc.Height)) { - IWineD3DSurface_LoadLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, NULL); - break; - } - break; - } - } - - target->get_drawable_size(target, &drawable_width, &drawable_height); - - /* This is for offscreen rendering as well as for multithreading, thus activate the set render target - * and not the last active one. - */ - ActivateContext(This, This->render_targets[0], CTXUSAGE_CLEAR); - ENTER_GL(); - - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - apply_fbo_state(iface); - } - - /* Only set the values up once, as they are not changing */ - if (Flags & WINED3DCLEAR_STENCIL) { - glClearStencil(Stencil); - checkGLcall("glClearStencil"); - glMask = glMask | GL_STENCIL_BUFFER_BIT; - glStencilMask(0xFFFFFFFF); - } - - if (Flags & WINED3DCLEAR_ZBUFFER) { - glDepthMask(GL_TRUE); - glClearDepth(Z); - checkGLcall("glClearDepth"); - glMask = glMask | GL_DEPTH_BUFFER_BIT; - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_ZWRITEENABLE)); - } - - if (Flags & WINED3DCLEAR_TARGET) { - TRACE("Clearing screen with glClear to color %x\n", Color); - glClearColor(D3DCOLOR_R(Color), - D3DCOLOR_G(Color), - D3DCOLOR_B(Color), - D3DCOLOR_A(Color)); - checkGLcall("glClearColor"); - - /* Clear ALL colors! */ - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glMask = glMask | GL_COLOR_BUFFER_BIT; - } - - vp_rect.left = vp->X; - vp_rect.top = vp->Y; - vp_rect.right = vp->X + vp->Width; - vp_rect.bottom = vp->Y + vp->Height; - if (!(Count > 0 && pRects)) { - if(This->stateBlock->renderState[WINED3DRS_SCISSORTESTENABLE]) { - IntersectRect(&vp_rect, &vp_rect, &This->stateBlock->scissorRect); - } - if(This->render_offscreen) { - glScissor(vp_rect.left, vp_rect.top, - vp_rect.right - vp_rect.left, vp_rect.bottom - vp_rect.top); - } else { - glScissor(vp_rect.left, drawable_height - vp_rect.bottom, - vp_rect.right - vp_rect.left, vp_rect.bottom - vp_rect.top); - } - checkGLcall("glScissor"); - glClear(glMask); - checkGLcall("glClear"); - } else { - /* Now process each rect in turn */ - for (i = 0; i < Count; i++) { - /* Note gl uses lower left, width/height */ - IntersectRect((RECT *) &curRect, &vp_rect, (RECT *) &pRects[i]); - if(This->stateBlock->renderState[WINED3DRS_SCISSORTESTENABLE]) { - IntersectRect((RECT *) &curRect, (RECT *) &curRect, &This->stateBlock->scissorRect); - } - TRACE("(%p) Rect=(%d,%d)->(%d,%d) glRect=(%d,%d), len=%d, hei=%d\n", This, - pRects[i].x1, pRects[i].y1, pRects[i].x2, pRects[i].y2, - curRect.x1, (target->currentDesc.Height - curRect.y2), - curRect.x2 - curRect.x1, curRect.y2 - curRect.y1); - - /* Tests show that rectangles where x1 > x2 or y1 > y2 are ignored silently. - * The rectangle is not cleared, no error is returned, but further rectanlges are - * still cleared if they are valid - */ - if(curRect.x1 > curRect.x2 || curRect.y1 > curRect.y2) { - TRACE("Rectangle with negative dimensions, ignoring\n"); - continue; - } - - if(This->render_offscreen) { - glScissor(curRect.x1, curRect.y1, - curRect.x2 - curRect.x1, curRect.y2 - curRect.y1); - } else { - glScissor(curRect.x1, drawable_height - curRect.y2, - curRect.x2 - curRect.x1, curRect.y2 - curRect.y1); - } - checkGLcall("glScissor"); - - glClear(glMask); - checkGLcall("glClear"); - } - } - - /* Restore the old values (why..?) */ - if (Flags & WINED3DCLEAR_STENCIL) { - glStencilMask(This->stateBlock->renderState[WINED3DRS_STENCILWRITEMASK]); - } - if (Flags & WINED3DCLEAR_TARGET) { - DWORD mask = This->stateBlock->renderState[WINED3DRS_COLORWRITEENABLE]; - glColorMask(mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE, - mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE, - mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE, - mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE); - - /* Dirtify the target surface for now. If the surface is locked regularly, and an up to date sysmem copy exists, - * it is most likely more efficient to perform a clear on the sysmem copy too instead of downloading it - */ - IWineD3DSurface_ModifyLocation(This->lastActiveRenderTarget, SFLAG_INDRAWABLE, TRUE); - /* TODO: Move the fbo logic into ModifyLocation() */ - if(This->render_offscreen && wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - target->Flags |= SFLAG_INTEXTURE; - } - } - LEAVE_GL(); - - return WINED3D_OK; + return IWineD3DDeviceImpl_ClearSurface(This, target, Count, pRects, Flags, Color, Z, Stencil); } /*****