Commit 99bfd817 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Allow depth and stencil clears on surfaces other than the current depth / stencil buffer.

parent 419d6e9a
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Context and render target management in wined3d * Context and render target management in wined3d
* *
* Copyright 2007-2008 Stefan Dösinger for CodeWeavers * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
* Copyright 2009-2010 Henri Verbeet for CodeWeavers * Copyright 2009-2011 Henri Verbeet for CodeWeavers
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -1915,7 +1915,7 @@ static struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWineD3DSur ...@@ -1915,7 +1915,7 @@ static struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWineD3DSur
/* Context activation is done by the caller. */ /* Context activation is done by the caller. */
static void context_apply_draw_buffers(struct wined3d_context *context, UINT rt_count, IWineD3DSurfaceImpl **rts) static void context_apply_draw_buffers(struct wined3d_context *context, UINT rt_count, IWineD3DSurfaceImpl **rts)
{ {
if (!surface_is_offscreen(rts[0])) if (rt_count && !surface_is_offscreen(rts[0]))
{ {
ENTER_GL(); ENTER_GL();
glDrawBuffer(surface_get_gl_buffer(rts[0])); glDrawBuffer(surface_get_gl_buffer(rts[0]));
...@@ -1951,7 +1951,7 @@ static void context_apply_draw_buffers(struct wined3d_context *context, UINT rt_ ...@@ -1951,7 +1951,7 @@ static void context_apply_draw_buffers(struct wined3d_context *context, UINT rt_
} }
else else
{ {
glDrawBuffer(rts[0]->resource.device->offscreenBuffer); glDrawBuffer(rt_count ? rts[0]->resource.device->offscreenBuffer : GL_NONE);
checkGLcall("glDrawBuffer()"); checkGLcall("glDrawBuffer()");
} }
LEAVE_GL(); LEAVE_GL();
...@@ -2086,7 +2086,7 @@ BOOL context_apply_clear_state(struct wined3d_context *context, IWineD3DDeviceIm ...@@ -2086,7 +2086,7 @@ BOOL context_apply_clear_state(struct wined3d_context *context, IWineD3DDeviceIm
ENTER_GL(); ENTER_GL();
if (surface_is_offscreen(rts[0])) if (!rt_count || surface_is_offscreen(rts[0]))
{ {
for (i = 0; i < rt_count; ++i) for (i = 0; i < rt_count; ++i)
{ {
......
...@@ -652,15 +652,15 @@ static void prepare_ds_clear(IWineD3DSurfaceImpl *ds, struct wined3d_context *co ...@@ -652,15 +652,15 @@ static void prepare_ds_clear(IWineD3DSurfaceImpl *ds, struct wined3d_context *co
/* Do not call while under the GL lock. */ /* Do not call while under the GL lock. */
HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, IWineD3DSurfaceImpl **rts, HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, IWineD3DSurfaceImpl **rts,
UINT rect_count, const RECT *rects, const RECT *draw_rect, DWORD flags, IWineD3DSurfaceImpl *depth_stencil, UINT rect_count, const RECT *rects, const RECT *draw_rect,
const WINED3DCOLORVALUE *color, float depth, DWORD stencil) DWORD flags, const WINED3DCOLORVALUE *color, float depth, DWORD stencil)
{ {
const RECT *clear_rect = (rect_count > 0 && rects) ? (const RECT *)rects : NULL; const RECT *clear_rect = (rect_count > 0 && rects) ? (const RECT *)rects : NULL;
IWineD3DSurfaceImpl *depth_stencil = device->depth_stencil; IWineD3DSurfaceImpl *target = rt_count ? rts[0] : NULL;
IWineD3DSurfaceImpl *target = rts[0];
UINT drawable_width, drawable_height; UINT drawable_width, drawable_height;
struct wined3d_context *context; struct wined3d_context *context;
GLbitfield clear_mask = 0; GLbitfield clear_mask = 0;
BOOL render_offscreen;
unsigned int i; unsigned int i;
/* When we're clearing parts of the drawable, make sure that the target surface is well up to date in the /* When we're clearing parts of the drawable, make sure that the target surface is well up to date in the
...@@ -694,7 +694,17 @@ HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, I ...@@ -694,7 +694,17 @@ HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, I
return WINED3D_OK; return WINED3D_OK;
} }
target->get_drawable_size(context, &drawable_width, &drawable_height); if (target)
{
render_offscreen = context->render_offscreen;
target->get_drawable_size(context, &drawable_width, &drawable_height);
}
else
{
render_offscreen = FALSE;
drawable_width = depth_stencil->pow2Width;
drawable_height = depth_stencil->pow2Height;
}
ENTER_GL(); ENTER_GL();
...@@ -715,7 +725,7 @@ HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, I ...@@ -715,7 +725,7 @@ HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, I
if (flags & WINED3DCLEAR_ZBUFFER) if (flags & WINED3DCLEAR_ZBUFFER)
{ {
DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN; DWORD location = render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN;
if (location == SFLAG_DS_ONSCREEN && depth_stencil != device->onscreen_depth_stencil) if (location == SFLAG_DS_ONSCREEN && depth_stencil != device->onscreen_depth_stencil)
{ {
...@@ -752,7 +762,7 @@ HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, I ...@@ -752,7 +762,7 @@ HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, I
if (!clear_rect) if (!clear_rect)
{ {
if (context->render_offscreen) if (render_offscreen)
{ {
glScissor(draw_rect->left, draw_rect->top, glScissor(draw_rect->left, draw_rect->top,
draw_rect->right - draw_rect->left, draw_rect->bottom - draw_rect->top); draw_rect->right - draw_rect->left, draw_rect->bottom - draw_rect->top);
...@@ -789,7 +799,7 @@ HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, I ...@@ -789,7 +799,7 @@ HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, I
continue; continue;
} }
if (context->render_offscreen) if (render_offscreen)
{ {
glScissor(current_rect.left, current_rect.top, glScissor(current_rect.left, current_rect.top,
current_rect.right - current_rect.left, current_rect.bottom - current_rect.top); current_rect.right - current_rect.left, current_rect.bottom - current_rect.top);
...@@ -808,7 +818,8 @@ HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, I ...@@ -808,7 +818,8 @@ HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, I
LEAVE_GL(); LEAVE_GL();
if (wined3d_settings.strict_draw_ordering || (target->container.type == WINED3D_CONTAINER_SWAPCHAIN if (wined3d_settings.strict_draw_ordering || (flags & WINED3DCLEAR_TARGET
&& target->container.type == WINED3D_CONTAINER_SWAPCHAIN
&& target->container.u.swapchain->front_buffer == target)) && target->container.u.swapchain->front_buffer == target))
wglFlush(); /* Flush to ensure ordering across contexts. */ wglFlush(); /* Flush to ensure ordering across contexts. */
...@@ -4816,7 +4827,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Clear(IWineD3DDevice *iface, DWORD rect ...@@ -4816,7 +4827,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Clear(IWineD3DDevice *iface, DWORD rect
device_get_draw_rect(device, &draw_rect); device_get_draw_rect(device, &draw_rect);
return device_clear_render_targets(device, device->adapter->gl_info.limits.buffers, return device_clear_render_targets(device, device->adapter->gl_info.limits.buffers,
device->render_targets, rect_count, rects, &draw_rect, flags, &c, depth, stencil); device->render_targets, device->depth_stencil, rect_count, rects,
&draw_rect, flags, &c, depth, stencil);
} }
/***** /*****
......
...@@ -1112,7 +1112,7 @@ void surface_set_compatible_renderbuffer(IWineD3DSurfaceImpl *surface, IWineD3DS ...@@ -1112,7 +1112,7 @@ void surface_set_compatible_renderbuffer(IWineD3DSurfaceImpl *surface, IWineD3DS
unsigned int src_width, src_height; unsigned int src_width, src_height;
unsigned int width, height; unsigned int width, height;
if (rt->resource.format->id != WINED3DFMT_NULL) if (rt && rt->resource.format->id != WINED3DFMT_NULL)
{ {
width = rt->pow2Width; width = rt->pow2Width;
height = rt->pow2Height; height = rt->pow2Height;
...@@ -3897,16 +3897,10 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *dst_surface, ...@@ -3897,16 +3897,10 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *dst_surface,
/* Do not call while under the GL lock. */ /* Do not call while under the GL lock. */
static HRESULT wined3d_surface_depth_fill(IWineD3DSurfaceImpl *surface, const RECT *rect, float depth) static HRESULT wined3d_surface_depth_fill(IWineD3DSurfaceImpl *surface, const RECT *rect, float depth)
{ {
IWineD3DDeviceImpl *device = surface->resource.device; const RECT draw_rect = {0, 0, surface->resource.width, surface->resource.height};
if (surface != device->depth_stencil)
{
FIXME("Depth fill is only implemented for the current depth / stencil buffer.\n");
return WINED3DERR_INVALIDCALL;
}
return IWineD3DDevice_Clear((IWineD3DDevice *)device, !!rect, rect, return device_clear_render_targets(surface->resource.device, 0, NULL, surface,
WINED3DCLEAR_ZBUFFER, 0x00000000, depth, 0); !!rect, rect, &draw_rect, WINED3DCLEAR_ZBUFFER, 0, depth, 0);
} }
/* Do not call while under the GL lock. */ /* Do not call while under the GL lock. */
...@@ -4921,8 +4915,8 @@ static HRESULT ffp_blit_color_fill(IWineD3DDeviceImpl *device, IWineD3DSurfaceIm ...@@ -4921,8 +4915,8 @@ static HRESULT ffp_blit_color_fill(IWineD3DDeviceImpl *device, IWineD3DSurfaceIm
{ {
const RECT draw_rect = {0, 0, dst_surface->resource.width, dst_surface->resource.height}; const RECT draw_rect = {0, 0, dst_surface->resource.width, dst_surface->resource.height};
return device_clear_render_targets(device, 1 /* rt_count */, &dst_surface, 1 /* rect_count */, return device_clear_render_targets(device, 1, &dst_surface, NULL,
dst_rect, &draw_rect, WINED3DCLEAR_TARGET, color, 0.0f /* depth */, 0 /* stencil */); 1, dst_rect, &draw_rect, WINED3DCLEAR_TARGET, color, 0.0f, 0);
} }
const struct blit_shader ffp_blit = { const struct blit_shader ffp_blit = {
......
...@@ -1769,8 +1769,8 @@ struct IWineD3DDeviceImpl ...@@ -1769,8 +1769,8 @@ struct IWineD3DDeviceImpl
}; };
HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, IWineD3DSurfaceImpl **rts, HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, IWineD3DSurfaceImpl **rts,
UINT rect_count, const RECT *rects, const RECT *draw_rect, DWORD flags, IWineD3DSurfaceImpl *depth_stencil, UINT rect_count, const RECT *rects, const RECT *draw_rect,
const WINED3DCOLORVALUE *color, float depth, DWORD stencil) DECLSPEC_HIDDEN; DWORD flags, const WINED3DCOLORVALUE *color, float depth, DWORD stencil) DECLSPEC_HIDDEN;
BOOL device_context_add(IWineD3DDeviceImpl *device, struct wined3d_context *context) 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_context_remove(IWineD3DDeviceImpl *device, struct wined3d_context *context) DECLSPEC_HIDDEN;
void device_get_draw_rect(IWineD3DDeviceImpl *device, RECT *rect) DECLSPEC_HIDDEN; void device_get_draw_rect(IWineD3DDeviceImpl *device, RECT *rect) DECLSPEC_HIDDEN;
......
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