[PATCH 2/4] wined3d: Clear all render targets in an MRT setup.
Henri Verbeet
hverbeet at codeweavers.com
Fri Jul 23 04:31:03 CDT 2010
---
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 b8d35c7..48da3ce 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 4b87245..17a4b83 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 1fec33d..7abae54 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 0a493e7..d366945 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;
--
1.7.1
More information about the wine-patches
mailing list