From c5de1e10450ba78e9b9bda8d8c3a201073967fbc Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Mon, 19 Apr 2010 20:47:01 +0200 Subject: [PATCH] wined3d: Store the depth/stencil surface as an IWineD3DSurfaceImpl pointer in the device. --- dlls/wined3d/context.c | 20 +++++----- dlls/wined3d/device.c | 72 ++++++++++++++++------------------ dlls/wined3d/drawprim.c | 7 ++-- dlls/wined3d/state.c | 8 ++-- dlls/wined3d/surface.c | 7 ++-- dlls/wined3d/swapchain.c | 6 +-- dlls/wined3d/wined3d_private.h | 2 +- 7 files changed, 59 insertions(+), 63 deletions(-) diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index dc542498931..716ec559da4 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -327,7 +327,7 @@ static struct fbo_entry *context_create_fbo_entry(struct wined3d_context *contex entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry)); entry->render_targets = HeapAlloc(GetProcessHeap(), 0, gl_info->limits.buffers * sizeof(*entry->render_targets)); memcpy(entry->render_targets, device->render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets)); - entry->depth_stencil = (IWineD3DSurfaceImpl *)device->stencilBufferTarget; + entry->depth_stencil = device->depth_stencil; entry->attached = FALSE; entry->id = 0; @@ -344,7 +344,7 @@ static void context_reuse_fbo_entry(struct wined3d_context *context, struct fbo_ context_clean_fbo_attachments(gl_info); memcpy(entry->render_targets, device->render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets)); - entry->depth_stencil = (IWineD3DSurfaceImpl *)device->stencilBufferTarget; + entry->depth_stencil = device->depth_stencil; entry->attached = FALSE; } @@ -374,7 +374,7 @@ static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context) { if (!memcmp(entry->render_targets, device->render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets)) - && entry->depth_stencil == (IWineD3DSurfaceImpl *)device->stencilBufferTarget) + && entry->depth_stencil == device->depth_stencil) { list_remove(&entry->entry); list_add_head(&context->fbo_list, &entry->entry); @@ -417,12 +417,12 @@ static void context_apply_fbo_entry(struct wined3d_context *context, struct fbo_ } /* Apply depth targets */ - if (device->stencilBufferTarget) + if (device->depth_stencil) { - surface_set_compatible_renderbuffer((IWineD3DSurfaceImpl *)device->stencilBufferTarget, + surface_set_compatible_renderbuffer(device->depth_stencil, device->render_targets[0]->pow2Width, device->render_targets[0]->pow2Height); } - context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, (IWineD3DSurfaceImpl *)device->stencilBufferTarget, TRUE); + context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, device->depth_stencil, TRUE); entry->attached = TRUE; } @@ -433,8 +433,8 @@ static void context_apply_fbo_entry(struct wined3d_context *context, struct fbo_ if (device->render_targets[i]) context_apply_attachment_filter_states(device->render_targets[i]); } - if (device->stencilBufferTarget) - context_apply_attachment_filter_states((IWineD3DSurfaceImpl *)device->stencilBufferTarget); + if (device->depth_stencil) + context_apply_attachment_filter_states(device->depth_stencil); } for (i = 0; i < gl_info->limits.buffers; ++i) @@ -1958,8 +1958,8 @@ static BOOL match_depth_stencil_format(const struct wined3d_format_desc *existin static void context_validate_onscreen_formats(IWineD3DDeviceImpl *device, struct wined3d_context *context) { /* Onscreen surfaces are always in a swapchain */ - IWineD3DSurfaceImpl *depth_stencil = (IWineD3DSurfaceImpl *) device->stencilBufferTarget; - IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) ((IWineD3DSurfaceImpl *)context->current_rt)->container; + IWineD3DSurfaceImpl *depth_stencil = device->depth_stencil; + IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)((IWineD3DSurfaceImpl *)context->current_rt)->container; if (!depth_stencil) return; if (match_depth_stencil_format(swapchain->ds_format, depth_stencil->resource.format_desc)) return; diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 09cafd731cb..64d884e6b77 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1621,10 +1621,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, IWineD3DSurface_AddRef((IWineD3DSurface *)This->render_targets[0]); /* Depth Stencil support */ - This->stencilBufferTarget = (IWineD3DSurface *)This->auto_depth_stencil; - if (NULL != This->stencilBufferTarget) { - IWineD3DSurface_AddRef(This->stencilBufferTarget); - } + This->depth_stencil = This->auto_depth_stencil; + if (This->depth_stencil) + IWineD3DSurface_AddRef((IWineD3DSurface *)This->depth_stencil); hr = This->shader_backend->shader_alloc_private(iface); if(FAILED(hr)) { @@ -1854,13 +1853,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, This->shader_backend->shader_free_private(iface); /* Release the buffers (with sanity checks)*/ - TRACE("Releasing the depth stencil buffer at %p\n", This->stencilBufferTarget); - if (This->stencilBufferTarget != NULL && IWineD3DSurface_Release(This->stencilBufferTarget)) + TRACE("Releasing the depth stencil buffer at %p\n", This->depth_stencil); + if (This->depth_stencil && IWineD3DSurface_Release((IWineD3DSurface *)This->depth_stencil)) { - if (This->auto_depth_stencil != (IWineD3DSurfaceImpl *)This->stencilBufferTarget) - FIXME("(%p) Something's still holding the stencilBufferTarget\n",This); + if (This->auto_depth_stencil != This->depth_stencil) + FIXME("(%p) Something is still holding the depth/stencil buffer.\n",This); } - This->stencilBufferTarget = NULL; + This->depth_stencil = NULL; TRACE("Releasing the render target at %p\n", This->render_targets[0]); IWineD3DSurface_Release((IWineD3DSurface *)This->render_targets[0]); @@ -4353,13 +4352,13 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfac IWineD3DStateBlockImpl *stateblock = This->stateBlock; const RECT *scissor_rect = stateblock->renderState[WINED3DRS_SCISSORTESTENABLE] ? &stateblock->scissorRect : NULL; const WINED3DRECT *clear_rect = (Count > 0 && pRects) ? pRects : NULL; + IWineD3DSurfaceImpl *depth_stencil = This->depth_stencil; const WINED3DVIEWPORT *vp = &stateblock->viewport; GLbitfield glMask = 0; unsigned int i; WINED3DRECT curRect; RECT vp_rect; UINT drawable_width, drawable_height; - IWineD3DSurfaceImpl *depth_stencil = (IWineD3DSurfaceImpl *) This->stencilBufferTarget; struct wined3d_context *context; /* When we're clearing parts of the drawable, make sure that the target surface is well up to date in the @@ -4537,7 +4536,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Clear(IWineD3DDevice *iface, DWORD Coun TRACE("(%p) Count (%d), pRects (%p), Flags (%x), Color (0x%08x), Z (%f), Stencil (%d)\n", This, Count, pRects, Flags, Color, Z, Stencil); - if(Flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL) && This->stencilBufferTarget == NULL) { + if (Flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL) && !This->depth_stencil) + { WARN("Clearing depth and/or stencil without a depth stencil buffer attached, returning WINED3DERR_INVALIDCALL\n"); /* TODO: What about depth stencil buffers without stencil bits? */ return WINED3DERR_INVALIDCALL; @@ -5693,7 +5693,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetFrontBackBuffers(IWineD3DDevice *ifa static HRESULT WINAPI IWineD3DDeviceImpl_GetDepthStencilSurface(IWineD3DDevice* iface, IWineD3DSurface **ppZStencilSurface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - *ppZStencilSurface = This->stencilBufferTarget; + *ppZStencilSurface = (IWineD3DSurface *)This->depth_stencil; TRACE("(%p) : zStencilSurface returning %p\n", This, *ppZStencilSurface); if(*ppZStencilSurface != NULL) { @@ -5906,41 +5906,38 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetRenderTarget(IWineD3DDevice *iface, static HRESULT WINAPI IWineD3DDeviceImpl_SetDepthStencilSurface(IWineD3DDevice *iface, IWineD3DSurface *pNewZStencil) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - HRESULT hr = WINED3D_OK; - IWineD3DSurface *tmp; + IWineD3DSurfaceImpl *tmp; + HRESULT hr = WINED3D_OK; - TRACE("(%p) Swapping z-buffer. Old = %p, new = %p\n",This, This->stencilBufferTarget, pNewZStencil); + TRACE("device %p, depth_stencil %p, old depth_stencil %p.\n", This, pNewZStencil, This->depth_stencil); - if (pNewZStencil == This->stencilBufferTarget) { - TRACE("Trying to do a NOP SetRenderTarget operation\n"); - } else { - /** OpenGL doesn't support 'sharing' of the stencilBuffer so we may incur an extra memory overhead - * depending on the renter target implementation being used. - * A shared context implementation will share all buffers between all rendertargets (including swapchains), - * implementations that use separate pbuffers for different swapchains or rendertargets will have to duplicate the - * stencil buffer and incur an extra memory overhead - ******************************************************/ - - if (This->stencilBufferTarget) { + if (This->depth_stencil == (IWineD3DSurfaceImpl *)pNewZStencil) + { + TRACE("Trying to do a NOP SetRenderTarget operation.\n"); + } + else + { + if (This->depth_stencil) + { if (((IWineD3DSwapChainImpl *)This->swapchains[0])->presentParms.Flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL - || ((IWineD3DSurfaceImpl *)This->stencilBufferTarget)->Flags & SFLAG_DISCARD) { - surface_modify_ds_location((IWineD3DSurfaceImpl *)This->stencilBufferTarget, SFLAG_DS_DISCARDED); + || This->depth_stencil->Flags & SFLAG_DISCARD) + { + surface_modify_ds_location(This->depth_stencil, SFLAG_DS_DISCARDED); } else { struct wined3d_context *context = context_acquire(This, (IWineD3DSurface *)This->render_targets[0], CTXUSAGE_RESOURCELOAD); - surface_load_ds_location((IWineD3DSurfaceImpl *)This->stencilBufferTarget, context, SFLAG_DS_OFFSCREEN); - surface_modify_ds_location((IWineD3DSurfaceImpl *)This->stencilBufferTarget, SFLAG_DS_OFFSCREEN); + surface_load_ds_location(This->depth_stencil, context, SFLAG_DS_OFFSCREEN); + surface_modify_ds_location(This->depth_stencil, SFLAG_DS_OFFSCREEN); context_release(context); } } - tmp = This->stencilBufferTarget; - This->stencilBufferTarget = pNewZStencil; - /* should we be calling the parent or the wined3d surface? */ - if (NULL != This->stencilBufferTarget) IWineD3DSurface_AddRef(This->stencilBufferTarget); - if (NULL != tmp) IWineD3DSurface_Release(tmp); + tmp = This->depth_stencil; + This->depth_stencil = (IWineD3DSurfaceImpl *)pNewZStencil; + if (This->depth_stencil) IWineD3DSurface_AddRef((IWineD3DSurface *)This->depth_stencil); + if (tmp) IWineD3DSurface_Release((IWineD3DSurface *)tmp); hr = WINED3D_OK; if((!tmp && pNewZStencil) || (!pNewZStencil && tmp)) { @@ -6693,9 +6690,8 @@ void device_resource_released(IWineD3DDeviceImpl *This, IWineD3DResource *resour if (This->render_targets[i] == (IWineD3DSurfaceImpl *)resource) This->render_targets[i] = NULL; } - if (This->stencilBufferTarget == (IWineD3DSurface *)resource) { - This->stencilBufferTarget = NULL; - } + if (This->depth_stencil == (IWineD3DSurfaceImpl *)resource) + This->depth_stencil = NULL; } break; diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index 590f31cf68f..fd199302fe0 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -602,7 +602,8 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT return; } - if (This->stencilBufferTarget) { + if (This->depth_stencil) + { /* Note that this depends on the context_acquire() call above to set * This->render_offscreen properly. We don't currently take the * Z-compare function into account, but we could skip loading the @@ -611,9 +612,9 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT DWORD location = context->render_offscreen ? SFLAG_DS_OFFSCREEN : SFLAG_DS_ONSCREEN; if (This->stateBlock->renderState[WINED3DRS_ZWRITEENABLE] || This->stateBlock->renderState[WINED3DRS_ZENABLE]) - surface_load_ds_location((IWineD3DSurfaceImpl *)This->stencilBufferTarget, context, location); + surface_load_ds_location(This->depth_stencil, context, location); if (This->stateBlock->renderState[WINED3DRS_ZWRITEENABLE]) - surface_modify_ds_location((IWineD3DSurfaceImpl *)This->stencilBufferTarget, location); + surface_modify_ds_location(This->depth_stencil, location); } /* Ok, we will be updating the screen from here onwards so grab the lock */ diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 64a87210659..ab8c32137f0 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -99,7 +99,7 @@ static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, stru static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { /* No z test without depth stencil buffers */ - if (!stateblock->device->stencilBufferTarget) + if (!stateblock->device->depth_stencil) { TRACE("No Z buffer - disabling depth test\n"); glDisable(GL_DEPTH_TEST); /* This also disables z writing in gl */ @@ -816,7 +816,7 @@ static void state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, struc GLint stencilPass_ccw = GL_KEEP; /* No stencil test without a stencil buffer. */ - if (!stateblock->device->stencilBufferTarget) + if (!stateblock->device->depth_stencil) { glDisable(GL_STENCIL_TEST); checkGLcall("glDisable GL_STENCIL_TEST"); @@ -899,7 +899,7 @@ static void state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, struc static void state_stencilwrite2s(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - DWORD mask = stateblock->device->stencilBufferTarget ? stateblock->renderState[WINED3DRS_STENCILWRITEMASK] : 0; + DWORD mask = stateblock->device->depth_stencil ? stateblock->renderState[WINED3DRS_STENCILWRITEMASK] : 0; GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK)); checkGLcall("glActiveStencilFaceEXT(GL_BACK)"); @@ -912,7 +912,7 @@ static void state_stencilwrite2s(DWORD state, IWineD3DStateBlockImpl *stateblock static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context) { - DWORD mask = stateblock->device->stencilBufferTarget ? stateblock->renderState[WINED3DRS_STENCILWRITEMASK] : 0; + DWORD mask = stateblock->device->depth_stencil ? stateblock->renderState[WINED3DRS_STENCILWRITEMASK] : 0; glStencilMask(mask); checkGLcall("glStencilMask"); diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index b6b59ab5a52..91baf9c3d99 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -1940,7 +1940,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) { This->dirtyRect.right = 0; This->dirtyRect.bottom = 0; } - else if (iface == device->stencilBufferTarget) + else if (This == device->depth_stencil) { FIXME("Depth Stencil buffer locking is not implemented\n"); } else { @@ -3796,7 +3796,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_Blt(IWineD3DSurface *iface, const RECT /* Accessing the depth stencil is supposed to fail between a BeginScene and EndScene pair, * except depth blits, which seem to work */ - if (iface == device->stencilBufferTarget || (SrcSurface && SrcSurface == device->stencilBufferTarget)) + if (This == device->depth_stencil || (Src && Src == device->depth_stencil)) { if (device->inScene && !(Flags & WINEDDBLT_DEPTHFILL)) { @@ -3836,8 +3836,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD return WINEDDERR_SURFACEBUSY; } - if (device->inScene && (iface == device->stencilBufferTarget - || (Source == device->stencilBufferTarget))) + if (device->inScene && (This == device->depth_stencil || srcImpl == device->depth_stencil)) { TRACE("Attempt to access the depth stencil surface in a BeginScene / EndScene pair, returning WINED3DERR_INVALIDCALL\n"); return WINED3DERR_INVALIDCALL; diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index c9f64e840bb..389efc2ac5a 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -459,12 +459,12 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO } } - if (This->device->stencilBufferTarget) + if (This->device->depth_stencil) { if (This->presentParms.Flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL - || ((IWineD3DSurfaceImpl *)This->device->stencilBufferTarget)->Flags & SFLAG_DISCARD) + || This->device->depth_stencil->Flags & SFLAG_DISCARD) { - surface_modify_ds_location((IWineD3DSurfaceImpl *)This->device->stencilBufferTarget, SFLAG_DS_DISCARDED); + surface_modify_ds_location(This->device->depth_stencil, SFLAG_DS_DISCARDED); } } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 59c0141e975..ec6ba22aa51 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1668,7 +1668,7 @@ struct IWineD3DDeviceImpl /* Render Target Support */ IWineD3DSurfaceImpl **render_targets; IWineD3DSurfaceImpl *auto_depth_stencil; - IWineD3DSurface *stencilBufferTarget; + IWineD3DSurfaceImpl *depth_stencil; /* palettes texture management */ UINT NumberOfPalettes;