From d374d85055490c37665bc68032dacb1de3e705d2 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Fri, 23 Jul 2010 11:31:03 +0200 Subject: [PATCH] wined3d: Clear all render targets in an MRT setup. --- dlls/wined3d/context.c | 58 ++++- dlls/wined3d/device.c | 444 +++++++++++++++++---------------- dlls/wined3d/surface.c | 7 +- dlls/wined3d/wined3d_private.h | 7 +- 4 files changed, 280 insertions(+), 236 deletions(-) diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index b8d35c7dd70..48da3ceaf47 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -473,7 +473,9 @@ void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target { if (surface_is_offscreen(render_target)) { + UINT clear_size = (context->gl_info->limits.buffers - 1) * sizeof(*context->blit_targets); context->blit_targets[0] = render_target; + if (clear_size) memset(&context->blit_targets[1], 0, clear_size); context_apply_fbo_state(context, target, context->blit_targets, depth_stencil); } else @@ -2059,30 +2061,64 @@ void context_apply_blit_state(struct wined3d_context *context, IWineD3DDeviceImp /* Context activation is done by the caller. */ void context_apply_clear_state(struct wined3d_context *context, IWineD3DDeviceImpl *device, - IWineD3DSurfaceImpl *render_target, IWineD3DSurfaceImpl *depth_stencil) + UINT rt_count, IWineD3DSurfaceImpl **rts, IWineD3DSurfaceImpl *depth_stencil) { const struct StateEntry *state_table = device->StateTable; - GLenum buffer; + UINT i; if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { context_validate_onscreen_formats(device, context, depth_stencil); ENTER_GL(); - context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, render_target, depth_stencil); + + if (surface_is_offscreen(rts[0])) + { + for (i = 0; i < rt_count; ++i) + { + context->blit_targets[i] = rts[i]; + } + while (i < context->gl_info->limits.buffers) + { + context->blit_targets[i] = NULL; + ++i; + } + context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets, depth_stencil); + } + else + { + context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, NULL); + } + LEAVE_GL(); } - if (!surface_is_offscreen(render_target)) - buffer = surface_get_gl_buffer(render_target); - else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) - buffer = GL_COLOR_ATTACHMENT0; + if (!surface_is_offscreen(rts[0])) + { + ENTER_GL(); + context_set_draw_buffer(context, surface_get_gl_buffer(rts[0])); + LEAVE_GL(); + } else - buffer = device->offscreenBuffer; + { + const struct wined3d_gl_info *gl_info = context->gl_info; + GLenum buffers[gl_info->limits.buffers]; - ENTER_GL(); - context_set_draw_buffer(context, buffer); - LEAVE_GL(); + for (i = 0; i < gl_info->limits.buffers; ++i) + { + if (i < rt_count && rts[i]) + buffers[i] = GL_COLOR_ATTACHMENT0 + i; + else + buffers[i] = GL_NONE; + } + + ENTER_GL(); + GL_EXTCALL(glDrawBuffersARB(gl_info->limits.buffers, buffers)); + checkGLcall("glDrawBuffers()"); + LEAVE_GL(); + + context->draw_buffer_dirty = TRUE; + } if (context->last_was_blit) { diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 4b87245f99d..17a4b832850 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -592,6 +592,228 @@ void device_switch_onscreen_ds(IWineD3DDeviceImpl *device, IWineD3DSurface_AddRef((IWineD3DSurface *)device->onscreen_depth_stencil); } +static BOOL is_full_clear(IWineD3DSurfaceImpl *target, const RECT *draw_rect, const RECT *clear_rect) +{ + /* partial draw rect */ + if (draw_rect->left || draw_rect->top + || draw_rect->right < target->currentDesc.Width + || draw_rect->bottom < target->currentDesc.Height) + return FALSE; + + /* partial clear rect */ + if (clear_rect && (clear_rect->left > 0 || clear_rect->top > 0 + || clear_rect->right < target->currentDesc.Width + || clear_rect->bottom < target->currentDesc.Height)) + return FALSE; + + return TRUE; +} + +static void prepare_ds_clear(IWineD3DSurfaceImpl *ds, struct wined3d_context *context, + DWORD location, const RECT *draw_rect, UINT rect_count, const RECT *clear_rect) +{ + RECT current_rect, r; + + if (ds->Flags & location) + SetRect(¤t_rect, 0, 0, + ds->ds_current_size.cx, + ds->ds_current_size.cy); + else + SetRectEmpty(¤t_rect); + + IntersectRect(&r, draw_rect, ¤t_rect); + if (EqualRect(&r, draw_rect)) + { + /* current_rect ⊇ draw_rect, modify only. */ + surface_modify_ds_location(ds, location, ds->ds_current_size.cx, ds->ds_current_size.cy); + return; + } + + if (EqualRect(&r, ¤t_rect)) + { + /* draw_rect ⊇ current_rect, test if we're doing a full clear. */ + + if (!clear_rect) + { + /* Full clear, modify only. */ + surface_modify_ds_location(ds, location, draw_rect->right, draw_rect->bottom); + return; + } + + IntersectRect(&r, draw_rect, clear_rect); + if (EqualRect(&r, draw_rect)) + { + /* clear_rect ⊇ draw_rect, modify only. */ + surface_modify_ds_location(ds, location, draw_rect->right, draw_rect->bottom); + return; + } + } + + /* Full load. */ + surface_load_ds_location(ds, context, location); + surface_modify_ds_location(ds, location, ds->ds_current_size.cx, ds->ds_current_size.cy); +} + +HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, IWineD3DSurfaceImpl **rts, + UINT rect_count, const WINED3DRECT *rects, DWORD flags, WINED3DCOLOR color, float depth, DWORD stencil) +{ + const RECT *clear_rect = (rect_count > 0 && rects) ? (const RECT *)rects : NULL; + IWineD3DSurfaceImpl *depth_stencil = device->depth_stencil; + IWineD3DSurfaceImpl *target = rts[0]; + UINT drawable_width, drawable_height; + struct wined3d_context *context; + GLbitfield clear_mask = 0; + unsigned int i; + RECT draw_rect; + + device_get_draw_rect(device, &draw_rect); + + /* 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 && !is_full_clear(target, &draw_rect, clear_rect)) + { + for (i = 0; i < rt_count; ++i) + { + if (rts[i]) surface_load_location(rts[i], SFLAG_INDRAWABLE, NULL); + } + } + + context = context_acquire(device, target); + if (!context->valid) + { + context_release(context); + WARN("Invalid context, skipping clear.\n"); + return WINED3D_OK; + } + + context_apply_clear_state(context, device, rt_count, rts, depth_stencil); + + target->get_drawable_size(context, &drawable_width, &drawable_height); + + ENTER_GL(); + + /* Only set the values up once, as they are not changing. */ + if (flags & WINED3DCLEAR_STENCIL) + { + if (context->gl_info->supported[EXT_STENCIL_TWO_SIDE]) + { + glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT); + IWineD3DDeviceImpl_MarkStateDirty(device, STATE_RENDER(WINED3DRS_TWOSIDEDSTENCILMODE)); + } + glStencilMask(~0U); + IWineD3DDeviceImpl_MarkStateDirty(device, STATE_RENDER(WINED3DRS_STENCILWRITEMASK)); + glClearStencil(stencil); + checkGLcall("glClearStencil"); + clear_mask = clear_mask | GL_STENCIL_BUFFER_BIT; + } + + if (flags & WINED3DCLEAR_ZBUFFER) + { + DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN; + + if (location == SFLAG_DS_ONSCREEN && depth_stencil != device->onscreen_depth_stencil) + device_switch_onscreen_ds(device, context, depth_stencil); + prepare_ds_clear(depth_stencil, context, location, &draw_rect, rect_count, clear_rect); + surface_modify_location(depth_stencil, SFLAG_INDRAWABLE, TRUE); + + glDepthMask(GL_TRUE); + IWineD3DDeviceImpl_MarkStateDirty(device, STATE_RENDER(WINED3DRS_ZWRITEENABLE)); + glClearDepth(depth); + checkGLcall("glClearDepth"); + clear_mask = clear_mask | GL_DEPTH_BUFFER_BIT; + } + + if (flags & WINED3DCLEAR_TARGET) + { + for (i = 0; i < rt_count; ++i) + { + if (rts[i]) surface_modify_location(rts[i], SFLAG_INDRAWABLE, TRUE); + } + + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + IWineD3DDeviceImpl_MarkStateDirty(device, STATE_RENDER(WINED3DRS_COLORWRITEENABLE)); + IWineD3DDeviceImpl_MarkStateDirty(device, STATE_RENDER(WINED3DRS_COLORWRITEENABLE1)); + IWineD3DDeviceImpl_MarkStateDirty(device, STATE_RENDER(WINED3DRS_COLORWRITEENABLE2)); + IWineD3DDeviceImpl_MarkStateDirty(device, STATE_RENDER(WINED3DRS_COLORWRITEENABLE3)); + glClearColor(D3DCOLOR_R(color), D3DCOLOR_G(color), D3DCOLOR_B(color), D3DCOLOR_A(color)); + checkGLcall("glClearColor"); + clear_mask = clear_mask | GL_COLOR_BUFFER_BIT; + } + + if (!clear_rect) + { + if (context->render_offscreen) + { + glScissor(draw_rect.left, draw_rect.top, + draw_rect.right - draw_rect.left, draw_rect.bottom - draw_rect.top); + } + else + { + glScissor(draw_rect.left, drawable_height - draw_rect.bottom, + draw_rect.right - draw_rect.left, draw_rect.bottom - draw_rect.top); + } + checkGLcall("glScissor"); + glClear(clear_mask); + checkGLcall("glClear"); + } + else + { + RECT current_rect; + + /* Now process each rect in turn. */ + for (i = 0; i < rect_count; ++i) + { + /* Note that GL uses lower left, width/height. */ + IntersectRect(¤t_rect, &draw_rect, &clear_rect[i]); + + TRACE("clear_rect[%u] %s, current_rect %s.\n", i, + wine_dbgstr_rect(&clear_rect[i]), + wine_dbgstr_rect(¤t_rect)); + + /* 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 (current_rect.left > current_rect.right || current_rect.top > current_rect.bottom) + { + TRACE("Rectangle with negative dimensions, ignoring.\n"); + continue; + } + + if (context->render_offscreen) + { + glScissor(current_rect.left, current_rect.top, + current_rect.right - current_rect.left, current_rect.bottom - current_rect.top); + } + else + { + glScissor(current_rect.left, drawable_height - current_rect.bottom, + current_rect.right - current_rect.left, current_rect.bottom - current_rect.top); + } + checkGLcall("glScissor"); + + glClear(clear_mask); + checkGLcall("glClear"); + } + } + + LEAVE_GL(); + + if (wined3d_settings.strict_draw_ordering || ((target->Flags & SFLAG_SWAPCHAIN) + && ((IWineD3DSwapChainImpl *)target->container)->front_buffer == target)) + wglFlush(); /* Flush to ensure ordering across contexts. */ + + context_release(context); + + return WINED3D_OK; +} + + /********************************************************** * IUnknown parts follows **********************************************************/ @@ -4358,223 +4580,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Present(IWineD3DDevice *iface, return WINED3D_OK; } -static BOOL is_full_clear(IWineD3DSurfaceImpl *target, const RECT *draw_rect, const RECT *clear_rect) -{ - /* partial draw rect */ - if (draw_rect->left || draw_rect->top - || draw_rect->right < target->currentDesc.Width - || draw_rect->bottom < target->currentDesc.Height) - return FALSE; - - /* partial clear rect */ - if (clear_rect && (clear_rect->left > 0 || clear_rect->top > 0 - || clear_rect->right < target->currentDesc.Width - || clear_rect->bottom < target->currentDesc.Height)) - return FALSE; - - return TRUE; -} - -static void prepare_ds_clear(IWineD3DSurfaceImpl *ds, struct wined3d_context *context, - DWORD location, const RECT *draw_rect, UINT rect_count, const RECT *clear_rect) -{ - RECT current_rect, r; - - if (ds->Flags & location) - SetRect(¤t_rect, 0, 0, - ds->ds_current_size.cx, - ds->ds_current_size.cy); - else - SetRectEmpty(¤t_rect); - - IntersectRect(&r, draw_rect, ¤t_rect); - if (EqualRect(&r, draw_rect)) - { - /* current_rect ⊇ draw_rect, modify only. */ - surface_modify_ds_location(ds, location, ds->ds_current_size.cx, ds->ds_current_size.cy); - return; - } - - if (EqualRect(&r, ¤t_rect)) - { - /* draw_rect ⊇ current_rect, test if we're doing a full clear. */ - - if (!clear_rect) - { - /* Full clear, modify only. */ - surface_modify_ds_location(ds, location, draw_rect->right, draw_rect->bottom); - return; - } - - IntersectRect(&r, draw_rect, clear_rect); - if (EqualRect(&r, draw_rect)) - { - /* clear_rect ⊇ draw_rect, modify only. */ - surface_modify_ds_location(ds, location, draw_rect->right, draw_rect->bottom); - return; - } - } - - /* Full load. */ - surface_load_ds_location(ds, context, location); - surface_modify_ds_location(ds, location, ds->ds_current_size.cx, ds->ds_current_size.cy); -} - -/* Not called from the VTable (internal subroutine) */ -HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, DWORD Count, - const WINED3DRECT *pRects, DWORD Flags, WINED3DCOLOR Color, float Z, DWORD Stencil) -{ - const RECT *clear_rect = (Count > 0 && pRects) ? (const RECT *)pRects : NULL; - IWineD3DSurfaceImpl *depth_stencil = This->depth_stencil; - GLbitfield glMask = 0; - unsigned int i; - UINT drawable_width, drawable_height; - struct wined3d_context *context; - RECT draw_rect; - - device_get_draw_rect(This, &draw_rect); - - /* 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)) - { - if (!is_full_clear(target, &draw_rect, clear_rect)) - surface_load_location(target, SFLAG_INDRAWABLE, NULL); - } - - context = context_acquire(This, target); - if (!context->valid) - { - context_release(context); - WARN("Invalid context, skipping clear.\n"); - return WINED3D_OK; - } - - context_apply_clear_state(context, This, target, depth_stencil); - - target->get_drawable_size(context, &drawable_width, &drawable_height); - - ENTER_GL(); - - /* Only set the values up once, as they are not changing */ - if (Flags & WINED3DCLEAR_STENCIL) - { - if (context->gl_info->supported[EXT_STENCIL_TWO_SIDE]) - { - glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT); - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_TWOSIDEDSTENCILMODE)); - } - glStencilMask(~0U); - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_STENCILWRITEMASK)); - glClearStencil(Stencil); - checkGLcall("glClearStencil"); - glMask = glMask | GL_STENCIL_BUFFER_BIT; - } - - if (Flags & WINED3DCLEAR_ZBUFFER) - { - DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN; - - if (location == SFLAG_DS_ONSCREEN && depth_stencil != This->onscreen_depth_stencil) - device_switch_onscreen_ds(This, context, depth_stencil); - prepare_ds_clear(depth_stencil, context, location, &draw_rect, Count, clear_rect); - surface_modify_location(depth_stencil, SFLAG_INDRAWABLE, TRUE); - - glDepthMask(GL_TRUE); - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_ZWRITEENABLE)); - glClearDepth(Z); - checkGLcall("glClearDepth"); - glMask = glMask | GL_DEPTH_BUFFER_BIT; - } - - if (Flags & WINED3DCLEAR_TARGET) - { - surface_modify_location(target, SFLAG_INDRAWABLE, TRUE); - - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE)); - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE1)); - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE2)); - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_COLORWRITEENABLE3)); - glClearColor(D3DCOLOR_R(Color), D3DCOLOR_G(Color), D3DCOLOR_B(Color), D3DCOLOR_A(Color)); - checkGLcall("glClearColor"); - glMask = glMask | GL_COLOR_BUFFER_BIT; - } - - if (!clear_rect) - { - if (context->render_offscreen) - { - glScissor(draw_rect.left, draw_rect.top, - draw_rect.right - draw_rect.left, draw_rect.bottom - draw_rect.top); - } - else - { - glScissor(draw_rect.left, drawable_height - draw_rect.bottom, - draw_rect.right - draw_rect.left, draw_rect.bottom - draw_rect.top); - } - checkGLcall("glScissor"); - glClear(glMask); - checkGLcall("glClear"); - } - else - { - RECT current_rect; - - /* Now process each rect in turn. */ - for (i = 0; i < Count; ++i) - { - /* Note gl uses lower left, width/height */ - IntersectRect(¤t_rect, &draw_rect, &clear_rect[i]); - - TRACE("clear_rect[%u] %s, current_rect %s.\n", i, - wine_dbgstr_rect(&clear_rect[i]), - wine_dbgstr_rect(¤t_rect)); - - /* 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 (current_rect.left > current_rect.right || current_rect.top > current_rect.bottom) - { - TRACE("Rectangle with negative dimensions, ignoring.\n"); - continue; - } - - if (context->render_offscreen) - { - glScissor(current_rect.left, current_rect.top, - current_rect.right - current_rect.left, current_rect.bottom - current_rect.top); - } - else - { - glScissor(current_rect.left, drawable_height - current_rect.bottom, - current_rect.right - current_rect.left, current_rect.bottom - current_rect.top); - } - checkGLcall("glScissor"); - - glClear(glMask); - checkGLcall("glClear"); - } - } - - LEAVE_GL(); - - if (wined3d_settings.strict_draw_ordering || ((target->Flags & SFLAG_SWAPCHAIN) - && ((IWineD3DSwapChainImpl *)target->container)->front_buffer == target)) - wglFlush(); /* Flush to ensure ordering across contexts. */ - - context_release(context); - - return WINED3D_OK; -} - static HRESULT WINAPI IWineD3DDeviceImpl_Clear(IWineD3DDevice *iface, DWORD Count, const WINED3DRECT *pRects, DWORD Flags, WINED3DCOLOR Color, float Z, DWORD Stencil) { @@ -4590,7 +4595,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Clear(IWineD3DDevice *iface, DWORD Coun return WINED3DERR_INVALIDCALL; } - return IWineD3DDeviceImpl_ClearSurface(This, This->render_targets[0], Count, pRects, Flags, Color, Z, Stencil); + return device_clear_render_targets(This, This->adapter->gl_info.limits.buffers, + This->render_targets, Count, pRects, Flags, Color, Z, Stencil); } /***** @@ -5493,7 +5499,7 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurfaceImpl *surface, surface_modify_location(surface, SFLAG_INDRAWABLE, TRUE); context = context_acquire(This, surface); - context_apply_clear_state(context, This, surface, NULL); + context_apply_clear_state(context, This, 1, &surface, NULL); ENTER_GL(); diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 1fec33d7dd2..7abae54fccf 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -4726,10 +4726,11 @@ static BOOL ffp_blit_supported(const struct wined3d_gl_info *gl_info, enum blit_ return FALSE; } -static HRESULT ffp_blit_color_fill(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect, DWORD fill_color) +static HRESULT ffp_blit_color_fill(IWineD3DDeviceImpl *device, + IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect, DWORD fill_color) { - return IWineD3DDeviceImpl_ClearSurface(device, dst_surface, 1 /* Number of rectangles */, - (const WINED3DRECT*)dst_rect, WINED3DCLEAR_TARGET, fill_color, 0.0f /* Z */, 0 /* Stencil */); + return device_clear_render_targets(device, 1 /* rt_count */, &dst_surface, 1 /* rect_count */, + (const WINED3DRECT *)dst_rect, WINED3DCLEAR_TARGET, fill_color, 0.0f /* depth */, 0 /* stencil */); } const struct blit_shader ffp_blit = { diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 0a493e71461..d366945a061 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1161,7 +1161,7 @@ void context_alloc_occlusion_query(struct wined3d_context *context, struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN; void context_apply_blit_state(struct wined3d_context *context, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN; void context_apply_clear_state(struct wined3d_context *context, IWineD3DDeviceImpl *device, - IWineD3DSurfaceImpl *render_target, IWineD3DSurfaceImpl *depth_stencil) DECLSPEC_HIDDEN; + UINT rt_count, IWineD3DSurfaceImpl **rts, IWineD3DSurfaceImpl *depth_stencil) DECLSPEC_HIDDEN; void context_apply_draw_state(struct wined3d_context *context, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN; void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target, IWineD3DSurfaceImpl *render_target, IWineD3DSurfaceImpl *depth_stencil) DECLSPEC_HIDDEN; @@ -1686,6 +1686,9 @@ struct IWineD3DDeviceImpl struct WineD3DRectPatch *currentPatch; }; +HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, + UINT rt_count, IWineD3DSurfaceImpl **rts, UINT rect_count, const WINED3DRECT *rects, + DWORD flags, WINED3DCOLOR color, float depth, DWORD stencil) DECLSPEC_HIDDEN; BOOL device_context_add(IWineD3DDeviceImpl *device, struct wined3d_context *context) DECLSPEC_HIDDEN; void device_context_remove(IWineD3DDeviceImpl *device, struct wined3d_context *context) DECLSPEC_HIDDEN; void device_get_draw_rect(IWineD3DDeviceImpl *device, RECT *rect) DECLSPEC_HIDDEN; @@ -1702,8 +1705,6 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, void device_switch_onscreen_ds(IWineD3DDeviceImpl *device, struct wined3d_context *context, IWineD3DSurfaceImpl *depth_stencil) DECLSPEC_HIDDEN; void device_update_stream_info(IWineD3DDeviceImpl *device, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; -HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, DWORD Count, - const WINED3DRECT *pRects, DWORD Flags, WINED3DCOLOR Color, float Z, DWORD Stencil) DECLSPEC_HIDDEN; void IWineD3DDeviceImpl_FindTexUnitMap(IWineD3DDeviceImpl *This) DECLSPEC_HIDDEN; void IWineD3DDeviceImpl_MarkStateDirty(IWineD3DDeviceImpl *This, DWORD state) DECLSPEC_HIDDEN;