1 /* 2 * IDirect3DStateBlock9 implementation 3 * 4 * Copyright 2002-2003 Raphael Junqueira 5 * Copyright 2002-2003 Jason Edmeades 6 * Copyright 2005 Oliver Stieber 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 21 */ 22 23 #include "config.h" 24 #include "d3d9_private.h" 25 26 WINE_DEFAULT_DEBUG_CHANNEL(d3d9); 27 28 static inline struct d3d9_stateblock *impl_from_IDirect3DStateBlock9(IDirect3DStateBlock9 *iface) 29 { 30 return CONTAINING_RECORD(iface, struct d3d9_stateblock, IDirect3DStateBlock9_iface); 31 } 32 33 static HRESULT WINAPI d3d9_stateblock_QueryInterface(IDirect3DStateBlock9 *iface, REFIID riid, void **out) 34 { 35 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); 36 37 if (IsEqualGUID(riid, &IID_IDirect3DStateBlock9) 38 || IsEqualGUID(riid, &IID_IUnknown)) 39 { 40 IDirect3DStateBlock9_AddRef(iface); 41 *out = iface; 42 return S_OK; 43 } 44 45 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); 46 47 *out = NULL; 48 return E_NOINTERFACE; 49 } 50 51 static ULONG WINAPI d3d9_stateblock_AddRef(IDirect3DStateBlock9 *iface) 52 { 53 struct d3d9_stateblock *stateblock = impl_from_IDirect3DStateBlock9(iface); 54 ULONG refcount = InterlockedIncrement(&stateblock->refcount); 55 56 TRACE("%p increasing refcount to %u.\n", iface, refcount); 57 58 return refcount; 59 } 60 61 static ULONG WINAPI d3d9_stateblock_Release(IDirect3DStateBlock9 *iface) 62 { 63 struct d3d9_stateblock *stateblock = impl_from_IDirect3DStateBlock9(iface); 64 ULONG refcount = InterlockedDecrement(&stateblock->refcount); 65 66 TRACE("%p decreasing refcount to %u.\n", iface, refcount); 67 68 if (!refcount) 69 { 70 wined3d_mutex_lock(); 71 wined3d_stateblock_decref(stateblock->wined3d_stateblock); 72 wined3d_mutex_unlock(); 73 74 IDirect3DDevice9Ex_Release(stateblock->parent_device); 75 heap_free(stateblock); 76 } 77 78 return refcount; 79 } 80 81 static HRESULT WINAPI d3d9_stateblock_GetDevice(IDirect3DStateBlock9 *iface, IDirect3DDevice9 **device) 82 { 83 struct d3d9_stateblock *stateblock = impl_from_IDirect3DStateBlock9(iface); 84 85 TRACE("iface %p, device %p.\n", iface, device); 86 87 *device = (IDirect3DDevice9 *)stateblock->parent_device; 88 IDirect3DDevice9_AddRef(*device); 89 90 TRACE("Returning device %p.\n", *device); 91 92 return D3D_OK; 93 } 94 95 static HRESULT WINAPI d3d9_stateblock_Capture(IDirect3DStateBlock9 *iface) 96 { 97 struct d3d9_stateblock *stateblock = impl_from_IDirect3DStateBlock9(iface); 98 99 TRACE("iface %p.\n", iface); 100 101 wined3d_mutex_lock(); 102 wined3d_stateblock_capture(stateblock->wined3d_stateblock); 103 wined3d_mutex_unlock(); 104 105 return D3D_OK; 106 } 107 108 static HRESULT WINAPI d3d9_stateblock_Apply(IDirect3DStateBlock9 *iface) 109 { 110 struct d3d9_stateblock *stateblock = impl_from_IDirect3DStateBlock9(iface); 111 112 TRACE("iface %p.\n", iface); 113 114 wined3d_mutex_lock(); 115 wined3d_stateblock_apply(stateblock->wined3d_stateblock); 116 wined3d_mutex_unlock(); 117 118 return D3D_OK; 119 } 120 121 122 static const struct IDirect3DStateBlock9Vtbl d3d9_stateblock_vtbl = 123 { 124 /* IUnknown */ 125 d3d9_stateblock_QueryInterface, 126 d3d9_stateblock_AddRef, 127 d3d9_stateblock_Release, 128 /* IDirect3DStateBlock9 */ 129 d3d9_stateblock_GetDevice, 130 d3d9_stateblock_Capture, 131 d3d9_stateblock_Apply, 132 }; 133 134 HRESULT stateblock_init(struct d3d9_stateblock *stateblock, struct d3d9_device *device, 135 D3DSTATEBLOCKTYPE type, struct wined3d_stateblock *wined3d_stateblock) 136 { 137 HRESULT hr; 138 139 stateblock->IDirect3DStateBlock9_iface.lpVtbl = &d3d9_stateblock_vtbl; 140 stateblock->refcount = 1; 141 142 if (wined3d_stateblock) 143 { 144 stateblock->wined3d_stateblock = wined3d_stateblock; 145 } 146 else 147 { 148 wined3d_mutex_lock(); 149 hr = wined3d_stateblock_create(device->wined3d_device, 150 (enum wined3d_stateblock_type)type, &stateblock->wined3d_stateblock); 151 wined3d_mutex_unlock(); 152 if (FAILED(hr)) 153 { 154 WARN("Failed to create wined3d stateblock, hr %#x.\n", hr); 155 return hr; 156 } 157 } 158 159 stateblock->parent_device = &device->IDirect3DDevice9Ex_iface; 160 IDirect3DDevice9Ex_AddRef(stateblock->parent_device); 161 162 return D3D_OK; 163 } 164