/*
* IDirect3DVolume8 implementation
*
- * Copyright 2002 Jason Edmeades
+ * Copyright 2005 Oliver Stieber
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "windef.h"
-#include "winbase.h"
-#include "winuser.h"
-#include "wingdi.h"
-#include "wine/debug.h"
-
+#include "config.h"
#include "d3d8_private.h"
-WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
-/* IDirect3DVolume IUnknown parts follow: */
-HRESULT WINAPI IDirect3DVolume8Impl_QueryInterface(LPDIRECT3DVOLUME8 iface,REFIID riid,LPVOID *ppobj)
-{
- ICOM_THIS(IDirect3DVolume8Impl,iface);
+/* IDirect3DVolume8 IUnknown parts follow: */
+static HRESULT WINAPI IDirect3DVolume8Impl_QueryInterface(LPDIRECT3DVOLUME8 iface, REFIID riid, LPVOID *ppobj) {
+ IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
+
+ TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), ppobj);
if (IsEqualGUID(riid, &IID_IUnknown)
|| IsEqualGUID(riid, &IID_IDirect3DVolume8)) {
- IDirect3DVolume8Impl_AddRef(iface);
+ IUnknown_AddRef(iface);
*ppobj = This;
- return D3D_OK;
+ return S_OK;
}
- WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
+ WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
+ *ppobj = NULL;
return E_NOINTERFACE;
}
-ULONG WINAPI IDirect3DVolume8Impl_AddRef(LPDIRECT3DVOLUME8 iface) {
- ICOM_THIS(IDirect3DVolume8Impl,iface);
- TRACE("(%p) : AddRef from %ld\n", This, This->ref);
- return ++(This->ref);
-}
+static ULONG WINAPI IDirect3DVolume8Impl_AddRef(LPDIRECT3DVOLUME8 iface) {
+ IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
+
+ TRACE("iface %p.\n", iface);
+
+ if (This->forwardReference) {
+ /* Forward to the containerParent */
+ TRACE("(%p) : Forwarding to %p\n", This, This->forwardReference);
+ return IUnknown_AddRef(This->forwardReference);
+ } else {
+ /* No container, handle our own refcounting */
+ ULONG ref = InterlockedIncrement(&This->ref);
+
+ TRACE("%p increasing refcount to %u.\n", iface, ref);
+
+ if (ref == 1)
+ {
+ wined3d_mutex_lock();
+ IWineD3DVolume_AddRef(This->wineD3DVolume);
+ wined3d_mutex_unlock();
+ }
-ULONG WINAPI IDirect3DVolume8Impl_Release(LPDIRECT3DVOLUME8 iface) {
- ICOM_THIS(IDirect3DVolume8Impl,iface);
- ULONG ref = --This->ref;
- TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
- if (ref == 0) {
- HeapFree(GetProcessHeap(), 0, This->allocatedMemory);
- HeapFree(GetProcessHeap(), 0, This);
+ return ref;
}
- return ref;
}
-/* IDirect3DVolume8: */
-HRESULT WINAPI IDirect3DVolume8Impl_GetDevice(LPDIRECT3DVOLUME8 iface, IDirect3DDevice8** ppDevice) {
- ICOM_THIS(IDirect3DVolume8Impl,iface);
- TRACE("(%p) : returning %p\n", This, This->Device);
- *ppDevice = (LPDIRECT3DDEVICE8) This->Device;
+static ULONG WINAPI IDirect3DVolume8Impl_Release(LPDIRECT3DVOLUME8 iface) {
+ IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
- /* Note Calling this method will increase the internal reference count
- on the IDirect3DDevice8 interface. */
- IDirect3DDevice8Impl_AddRef(*ppDevice);
+ TRACE("iface %p.\n", iface);
- return D3D_OK;
-}
-HRESULT WINAPI IDirect3DVolume8Impl_SetPrivateData(LPDIRECT3DVOLUME8 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
- ICOM_THIS(IDirect3DVolume8Impl,iface);
- FIXME("(%p) : stub\n", This); return D3D_OK;
+ if (This->forwardReference) {
+ /* Forward to the containerParent */
+ TRACE("(%p) : Forwarding to %p\n", This, This->forwardReference);
+ return IUnknown_Release(This->forwardReference);
+ }
+ else {
+ /* No container, handle our own refcounting */
+ ULONG ref = InterlockedDecrement(&This->ref);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, ref);
+
+ if (ref == 0) {
+ wined3d_mutex_lock();
+ IWineD3DVolume_Release(This->wineD3DVolume);
+ wined3d_mutex_unlock();
+ }
+
+ return ref;
+ }
}
-HRESULT WINAPI IDirect3DVolume8Impl_GetPrivateData(LPDIRECT3DVOLUME8 iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
- ICOM_THIS(IDirect3DVolume8Impl,iface);
- FIXME("(%p) : stub\n", This); return D3D_OK;
+
+/* IDirect3DVolume8 Interface follow: */
+static HRESULT WINAPI IDirect3DVolume8Impl_GetDevice(IDirect3DVolume8 *iface, IDirect3DDevice8 **device)
+{
+ IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
+ IDirect3DResource8 *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, device %p.\n", iface, device);
+
+ hr = IUnknown_QueryInterface(This->forwardReference, &IID_IDirect3DResource8, (void **)&resource);
+ if (SUCCEEDED(hr))
+ {
+ hr = IDirect3DResource8_GetDevice(resource, device);
+ IDirect3DResource8_Release(resource);
+
+ TRACE("Returning device %p.\n", *device);
+ }
+
+ return hr;
}
-HRESULT WINAPI IDirect3DVolume8Impl_FreePrivateData(LPDIRECT3DVOLUME8 iface, REFGUID refguid) {
- ICOM_THIS(IDirect3DVolume8Impl,iface);
- FIXME("(%p) : stub\n", This); return D3D_OK;
+
+static HRESULT WINAPI IDirect3DVolume8Impl_SetPrivateData(LPDIRECT3DVOLUME8 iface, REFGUID refguid, CONST void *pData, DWORD SizeOfData, DWORD Flags) {
+ IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
+ iface, debugstr_guid(refguid), pData, SizeOfData, Flags);
+
+ wined3d_mutex_lock();
+ hr = IWineD3DVolume_SetPrivateData(This->wineD3DVolume, refguid, pData, SizeOfData, Flags);
+ wined3d_mutex_unlock();
+
+ return hr;
}
-HRESULT WINAPI IDirect3DVolume8Impl_GetContainer(LPDIRECT3DVOLUME8 iface, REFIID riid, void** ppContainer) {
- ICOM_THIS(IDirect3DVolume8Impl,iface);
- TRACE("(%p) : returning %p\n", This, This->Container);
- *ppContainer = This->Container;
- return D3D_OK;
+static HRESULT WINAPI IDirect3DVolume8Impl_GetPrivateData(LPDIRECT3DVOLUME8 iface, REFGUID refguid, void *pData, DWORD* pSizeOfData) {
+ IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %p.\n",
+ iface, debugstr_guid(refguid), pData, pSizeOfData);
+
+ wined3d_mutex_lock();
+ hr = IWineD3DVolume_GetPrivateData(This->wineD3DVolume, refguid, pData, pSizeOfData);
+ wined3d_mutex_unlock();
+
+ return hr;
}
-HRESULT WINAPI IDirect3DVolume8Impl_GetDesc(LPDIRECT3DVOLUME8 iface, D3DVOLUME_DESC* pDesc) {
- ICOM_THIS(IDirect3DVolume8Impl,iface);
- TRACE("(%p) : copying into %p\n", This, pDesc);
- memcpy(pDesc, &This->myDesc, sizeof(D3DVOLUME_DESC));
- return D3D_OK;
+
+static HRESULT WINAPI IDirect3DVolume8Impl_FreePrivateData(LPDIRECT3DVOLUME8 iface, REFGUID refguid) {
+ IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s.\n", iface, debugstr_guid(refguid));
+
+ wined3d_mutex_lock();
+ hr = IWineD3DVolume_FreePrivateData(This->wineD3DVolume, refguid);
+ wined3d_mutex_unlock();
+
+ return hr;
}
-HRESULT WINAPI IDirect3DVolume8Impl_LockBox(LPDIRECT3DVOLUME8 iface, D3DLOCKED_BOX* pLockedVolume,CONST D3DBOX* pBox, DWORD Flags) {
- ICOM_THIS(IDirect3DVolume8Impl,iface);
- FIXME("(%p) : pBox=%p stub\n", This, pBox);
-
- /* fixme: should we really lock as such? */
- TRACE("(%p) : box=%p, output pbox=%p, allMem=%p\n", This, pBox, pLockedVolume, This->allocatedMemory);
-
- pLockedVolume->RowPitch = This->bytesPerPixel * This->myDesc.Width; /* Bytes / row */
- pLockedVolume->SlicePitch = This->bytesPerPixel * This->myDesc.Width * This->myDesc.Height; /* Bytes / slice */
- if (!pBox) {
- TRACE("No box supplied - all is ok\n");
- pLockedVolume->pBits = This->allocatedMemory;
- } else {
- TRACE("Lock Box (%p) = l %d, t %d, r %d, b %d, fr %d, ba %d\n", pBox, pBox->Left, pBox->Top,
- pBox->Right, pBox->Bottom, pBox->Front, pBox->Back);
- pLockedVolume->pBits = This->allocatedMemory +
- (pLockedVolume->SlicePitch * pBox->Front) + /* FIXME: is front < back or vica versa? */
- (pLockedVolume->RowPitch * pBox->Top) +
- (pBox->Left * This->bytesPerPixel);
+
+static HRESULT WINAPI IDirect3DVolume8Impl_GetContainer(LPDIRECT3DVOLUME8 iface, REFIID riid, void **ppContainer) {
+ IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
+ HRESULT res;
+
+ TRACE("iface %p, riid %s, container %p.\n",
+ iface, debugstr_guid(riid), ppContainer);
+
+ if (!This->container) return E_NOINTERFACE;
+
+ if (!ppContainer) {
+ ERR("Called without a valid ppContainer.\n");
}
- TRACE("returning pBits=%p, rpitch=%d, spitch=%d\n", pLockedVolume->pBits, pLockedVolume->RowPitch, pLockedVolume->SlicePitch);
- return D3D_OK;
+ res = IUnknown_QueryInterface(This->container, riid, ppContainer);
+ TRACE("Returning ppContainer %p, *ppContainer %p\n", ppContainer, *ppContainer);
- return D3D_OK;
+ return res;
}
-HRESULT WINAPI IDirect3DVolume8Impl_UnlockBox(LPDIRECT3DVOLUME8 iface) {
- ICOM_THIS(IDirect3DVolume8Impl,iface);
- TRACE("(%p) : stub\n", This);
- if (This->Container) {
- IDirect3DVolumeTexture8 *cont = This->Container;
-
- int containerType = IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) cont);
- if (containerType == D3DRTYPE_VOLUMETEXTURE) {
- IDirect3DTexture8Impl *pTexture = (IDirect3DTexture8Impl *)cont;
- pTexture->Dirty = TRUE;
- } else {
- FIXME("Set dirty on container type %d\n", containerType);
- }
- }
+
+static HRESULT WINAPI IDirect3DVolume8Impl_GetDesc(LPDIRECT3DVOLUME8 iface, D3DVOLUME_DESC *pDesc) {
+ IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
+ WINED3DVOLUME_DESC wined3ddesc;
+
+ TRACE("iface %p, desc %p.\n", iface, pDesc);
+
+ wined3d_mutex_lock();
+ IWineD3DVolume_GetDesc(This->wineD3DVolume, &wined3ddesc);
+ wined3d_mutex_unlock();
+
+ pDesc->Format = d3dformat_from_wined3dformat(wined3ddesc.Format);
+ pDesc->Type = wined3ddesc.Type;
+ pDesc->Usage = wined3ddesc.Usage;
+ pDesc->Pool = wined3ddesc.Pool;
+ pDesc->Size = wined3ddesc.Size;
+ pDesc->Width = wined3ddesc.Width;
+ pDesc->Height = wined3ddesc.Height;
+ pDesc->Depth = wined3ddesc.Depth;
+
return D3D_OK;
}
+static HRESULT WINAPI IDirect3DVolume8Impl_LockBox(LPDIRECT3DVOLUME8 iface, D3DLOCKED_BOX *pLockedVolume, CONST D3DBOX *pBox, DWORD Flags) {
+ IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
+ HRESULT hr;
+
+ TRACE("iface %p, locked_box %p, box %p, flags %#x.\n",
+ iface, pLockedVolume, pBox, Flags);
+
+ wined3d_mutex_lock();
+ hr = IWineD3DVolume_Map(This->wineD3DVolume, (WINED3DLOCKED_BOX *)pLockedVolume,
+ (const WINED3DBOX *)pBox, Flags);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI IDirect3DVolume8Impl_UnlockBox(LPDIRECT3DVOLUME8 iface) {
+ IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
+ HRESULT hr;
-ICOM_VTABLE(IDirect3DVolume8) Direct3DVolume8_Vtbl =
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ hr = IWineD3DVolume_Unmap(This->wineD3DVolume);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static const IDirect3DVolume8Vtbl Direct3DVolume8_Vtbl =
{
- ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+ /* IUnknown */
IDirect3DVolume8Impl_QueryInterface,
IDirect3DVolume8Impl_AddRef,
IDirect3DVolume8Impl_Release,
+ /* IDirect3DVolume8 */
IDirect3DVolume8Impl_GetDevice,
IDirect3DVolume8Impl_SetPrivateData,
IDirect3DVolume8Impl_GetPrivateData,
IDirect3DVolume8Impl_LockBox,
IDirect3DVolume8Impl_UnlockBox
};
+
+static void STDMETHODCALLTYPE volume_wined3d_object_destroyed(void *parent)
+{
+ HeapFree(GetProcessHeap(), 0, parent);
+}
+
+static const struct wined3d_parent_ops d3d8_volume_wined3d_parent_ops =
+{
+ volume_wined3d_object_destroyed,
+};
+
+HRESULT volume_init(IDirect3DVolume8Impl *volume, IDirect3DDevice8Impl *device, UINT width, UINT height,
+ UINT depth, DWORD usage, enum wined3d_format_id format, WINED3DPOOL pool)
+{
+ HRESULT hr;
+
+ volume->lpVtbl = &Direct3DVolume8_Vtbl;
+ volume->ref = 1;
+
+ hr = IWineD3DDevice_CreateVolume(device->WineD3DDevice, width, height, depth, usage,
+ format, pool, volume, &d3d8_volume_wined3d_parent_ops, &volume->wineD3DVolume);
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d volume, hr %#x.\n", hr);
+ return hr;
+ }
+
+ return D3D_OK;
+}