1 /* 2 * IDirect3DVolume9 implementation 3 * 4 * Copyright 2002-2005 Jason Edmeades 5 * Raphael Junqueira 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22 #include "config.h" 23 #include "d3d9_private.h" 24 25 WINE_DEFAULT_DEBUG_CHANNEL(d3d9); 26 27 /* IDirect3DVolume9 IUnknown parts follow: */ 28 static HRESULT WINAPI IDirect3DVolume9Impl_QueryInterface(LPDIRECT3DVOLUME9 iface, REFIID riid, LPVOID* ppobj) { 29 IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface; 30 31 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), ppobj); 32 33 if (IsEqualGUID(riid, &IID_IUnknown) 34 || IsEqualGUID(riid, &IID_IDirect3DVolume9)) { 35 IDirect3DVolume9_AddRef(iface); 36 *ppobj = This; 37 return S_OK; 38 } 39 40 WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj); 41 *ppobj = NULL; 42 return E_NOINTERFACE; 43 } 44 45 static ULONG WINAPI IDirect3DVolume9Impl_AddRef(LPDIRECT3DVOLUME9 iface) { 46 IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface; 47 48 TRACE("iface %p.\n", iface); 49 50 if (This->forwardReference) { 51 /* Forward refcounting */ 52 TRACE("(%p) : Forwarding to %p\n", This, This->forwardReference); 53 return IUnknown_AddRef(This->forwardReference); 54 } else { 55 /* No container, handle our own refcounting */ 56 ULONG ref = InterlockedIncrement(&This->ref); 57 58 TRACE("%p increasing refcount to %u.\n", iface, ref); 59 60 if (ref == 1) 61 { 62 wined3d_mutex_lock(); 63 IWineD3DVolume_AddRef(This->wineD3DVolume); 64 wined3d_mutex_unlock(); 65 } 66 67 return ref; 68 } 69 } 70 71 static ULONG WINAPI IDirect3DVolume9Impl_Release(LPDIRECT3DVOLUME9 iface) { 72 IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface; 73 74 TRACE("iface %p.\n", iface); 75 76 if (This->forwardReference) { 77 /* Forward refcounting */ 78 TRACE("(%p) : Forwarding to %p\n", This, This->forwardReference); 79 return IUnknown_Release(This->forwardReference); 80 } else { 81 /* No container, handle our own refcounting */ 82 ULONG ref = InterlockedDecrement(&This->ref); 83 84 TRACE("%p decreasing refcount to %u.\n", iface, ref); 85 86 if (ref == 0) { 87 wined3d_mutex_lock(); 88 IWineD3DVolume_Release(This->wineD3DVolume); 89 wined3d_mutex_unlock(); 90 } 91 92 return ref; 93 } 94 } 95 96 /* IDirect3DVolume9 Interface follow: */ 97 static HRESULT WINAPI IDirect3DVolume9Impl_GetDevice(IDirect3DVolume9 *iface, IDirect3DDevice9 **device) 98 { 99 IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface; 100 IDirect3DResource9 *resource; 101 HRESULT hr; 102 103 TRACE("iface %p, device %p.\n", iface, device); 104 105 hr = IUnknown_QueryInterface(This->forwardReference, &IID_IDirect3DResource9, (void **)&resource); 106 if (SUCCEEDED(hr)) 107 { 108 hr = IDirect3DResource9_GetDevice(resource, device); 109 IDirect3DResource9_Release(resource); 110 111 TRACE("Returning device %p.\n", *device); 112 } 113 114 return hr; 115 } 116 117 static HRESULT WINAPI IDirect3DVolume9Impl_SetPrivateData(LPDIRECT3DVOLUME9 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) { 118 IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface; 119 HRESULT hr; 120 121 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n", 122 iface, debugstr_guid(refguid), pData, SizeOfData, Flags); 123 124 wined3d_mutex_lock(); 125 126 hr = IWineD3DVolume_SetPrivateData(This->wineD3DVolume, refguid, pData, SizeOfData, Flags); 127 128 wined3d_mutex_unlock(); 129 130 return hr; 131 } 132 133 static HRESULT WINAPI IDirect3DVolume9Impl_GetPrivateData(LPDIRECT3DVOLUME9 iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) { 134 IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface; 135 HRESULT hr; 136 137 TRACE("iface %p, guid %s, data %p, data_size %p.\n", 138 iface, debugstr_guid(refguid), pData, pSizeOfData); 139 140 wined3d_mutex_lock(); 141 142 hr = IWineD3DVolume_GetPrivateData(This->wineD3DVolume, refguid, pData, pSizeOfData); 143 144 wined3d_mutex_unlock(); 145 146 return hr; 147 } 148 149 static HRESULT WINAPI IDirect3DVolume9Impl_FreePrivateData(LPDIRECT3DVOLUME9 iface, REFGUID refguid) { 150 IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface; 151 HRESULT hr; 152 153 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(refguid)); 154 155 wined3d_mutex_lock(); 156 157 hr = IWineD3DVolume_FreePrivateData(This->wineD3DVolume, refguid); 158 159 wined3d_mutex_unlock(); 160 161 return hr; 162 } 163 164 static HRESULT WINAPI IDirect3DVolume9Impl_GetContainer(LPDIRECT3DVOLUME9 iface, REFIID riid, void** ppContainer) { 165 IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface; 166 HRESULT res; 167 168 TRACE("iface %p, riid %s, container %p.\n", iface, debugstr_guid(riid), ppContainer); 169 170 if (!This->container) return E_NOINTERFACE; 171 172 if (!ppContainer) { 173 ERR("Called without a valid ppContainer.\n"); 174 } 175 176 res = IUnknown_QueryInterface(This->container, riid, ppContainer); 177 178 TRACE("Returning ppContainer %p, *ppContainer %p\n", ppContainer, *ppContainer); 179 180 return res; 181 } 182 183 static HRESULT WINAPI IDirect3DVolume9Impl_GetDesc(LPDIRECT3DVOLUME9 iface, D3DVOLUME_DESC* pDesc) { 184 IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface; 185 WINED3DVOLUME_DESC wined3ddesc; 186 HRESULT hr; 187 188 TRACE("iface %p, desc %p.\n", iface, pDesc); 189 190 wined3d_mutex_lock(); 191 192 hr = IWineD3DVolume_GetDesc(This->wineD3DVolume, &wined3ddesc); 193 194 wined3d_mutex_unlock(); 195 196 if (SUCCEEDED(hr)) 197 { 198 pDesc->Format = d3dformat_from_wined3dformat(wined3ddesc.Format); 199 pDesc->Type = wined3ddesc.Type; 200 pDesc->Usage = wined3ddesc.Usage; 201 pDesc->Pool = wined3ddesc.Pool; 202 pDesc->Width = wined3ddesc.Width; 203 pDesc->Height = wined3ddesc.Height; 204 pDesc->Depth = wined3ddesc.Depth; 205 } 206 207 return hr; 208 } 209 210 static HRESULT WINAPI IDirect3DVolume9Impl_LockBox(LPDIRECT3DVOLUME9 iface, D3DLOCKED_BOX* pLockedVolume, CONST D3DBOX* pBox, DWORD Flags) { 211 IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface; 212 HRESULT hr; 213 214 TRACE("iface %p, locked_box %p, box %p, flags %#x.\n", 215 iface, pLockedVolume, pBox, Flags); 216 217 wined3d_mutex_lock(); 218 219 hr = IWineD3DVolume_LockBox(This->wineD3DVolume, (WINED3DLOCKED_BOX *)pLockedVolume, 220 (const WINED3DBOX *)pBox, Flags); 221 222 wined3d_mutex_unlock(); 223 224 return hr; 225 } 226 227 static HRESULT WINAPI IDirect3DVolume9Impl_UnlockBox(LPDIRECT3DVOLUME9 iface) { 228 IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface; 229 HRESULT hr; 230 231 TRACE("iface %p.\n", iface); 232 233 wined3d_mutex_lock(); 234 235 hr = IWineD3DVolume_UnlockBox(This->wineD3DVolume); 236 237 wined3d_mutex_unlock(); 238 239 return hr; 240 } 241 242 static const IDirect3DVolume9Vtbl Direct3DVolume9_Vtbl = 243 { 244 /* IUnknown */ 245 IDirect3DVolume9Impl_QueryInterface, 246 IDirect3DVolume9Impl_AddRef, 247 IDirect3DVolume9Impl_Release, 248 /* IDirect3DVolume9 */ 249 IDirect3DVolume9Impl_GetDevice, 250 IDirect3DVolume9Impl_SetPrivateData, 251 IDirect3DVolume9Impl_GetPrivateData, 252 IDirect3DVolume9Impl_FreePrivateData, 253 IDirect3DVolume9Impl_GetContainer, 254 IDirect3DVolume9Impl_GetDesc, 255 IDirect3DVolume9Impl_LockBox, 256 IDirect3DVolume9Impl_UnlockBox 257 }; 258 259 static void STDMETHODCALLTYPE volume_wined3d_object_destroyed(void *parent) 260 { 261 HeapFree(GetProcessHeap(), 0, parent); 262 } 263 264 static const struct wined3d_parent_ops d3d9_volume_wined3d_parent_ops = 265 { 266 volume_wined3d_object_destroyed, 267 }; 268 269 HRESULT volume_init(IDirect3DVolume9Impl *volume, IDirect3DDevice9Impl *device, UINT width, UINT height, 270 UINT depth, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool) 271 { 272 HRESULT hr; 273 274 volume->lpVtbl = &Direct3DVolume9_Vtbl; 275 volume->ref = 1; 276 277 hr = IWineD3DDevice_CreateVolume(device->WineD3DDevice, width, height, depth, usage & WINED3DUSAGE_MASK, 278 format, pool, &volume->wineD3DVolume, (IUnknown *)volume, &d3d9_volume_wined3d_parent_ops); 279 if (FAILED(hr)) 280 { 281 WARN("Failed to create wined3d volume, hr %#x.\n", hr); 282 return hr; 283 } 284 285 return D3D_OK; 286 } 287