blob: 84ee9a16cd6e82f0ecb96ec20803321e0b1f0380 [file] [log] [blame]
Henri Verbeet15491802010-09-01 18:41:04 +02001/*
2 * Copyright 2002-2004 Jason Edmeades
3 * Copyright 2002-2004 Raphael Junqueira
4 * Copyright 2005 Oliver Stieber
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include "config.h"
Michael Stefaniuc875d6902011-07-05 12:01:01 +020022#include <assert.h>
Henri Verbeet15491802010-09-01 18:41:04 +020023#include "d3d9_private.h"
24
25WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
26
Henri Verbeet469eba22011-06-16 22:38:26 +020027static inline IDirect3DVertexBuffer9Impl *impl_from_IDirect3DVertexBuffer9(IDirect3DVertexBuffer9 *iface)
28{
Michael Stefaniuc17eccaf2011-07-06 13:29:02 +020029 return CONTAINING_RECORD(iface, IDirect3DVertexBuffer9Impl, IDirect3DVertexBuffer9_iface);
Henri Verbeet469eba22011-06-16 22:38:26 +020030}
31
Henri Verbeet15491802010-09-01 18:41:04 +020032static HRESULT WINAPI d3d9_vertexbuffer_QueryInterface(IDirect3DVertexBuffer9 *iface, REFIID riid, void **object)
33{
34 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
35
36 if (IsEqualGUID(riid, &IID_IDirect3DVertexBuffer9)
37 || IsEqualGUID(riid, &IID_IDirect3DResource9)
38 || IsEqualGUID(riid, &IID_IUnknown))
39 {
40 IDirect3DVertexBuffer9_AddRef(iface);
41 *object = iface;
42 return S_OK;
43 }
44
45 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
46
47 *object = NULL;
48 return E_NOINTERFACE;
49}
50
51static ULONG WINAPI d3d9_vertexbuffer_AddRef(IDirect3DVertexBuffer9 *iface)
52{
Michael Stefaniuc17eccaf2011-07-06 13:29:02 +020053 IDirect3DVertexBuffer9Impl *buffer = impl_from_IDirect3DVertexBuffer9(iface);
Henri Verbeet15491802010-09-01 18:41:04 +020054 ULONG refcount = InterlockedIncrement(&buffer->ref);
55
56 TRACE("%p increasing refcount to %u.\n", iface, refcount);
57
58 if (refcount == 1)
59 {
60 IDirect3DDevice9Ex_AddRef(buffer->parentDevice);
61 wined3d_mutex_lock();
Henri Verbeeta27ee752011-03-03 21:49:09 +010062 wined3d_buffer_incref(buffer->wineD3DVertexBuffer);
Henri Verbeet15491802010-09-01 18:41:04 +020063 wined3d_mutex_unlock();
64 }
65
66 return refcount;
67}
68
69static ULONG WINAPI d3d9_vertexbuffer_Release(IDirect3DVertexBuffer9 *iface)
70{
Michael Stefaniuc17eccaf2011-07-06 13:29:02 +020071 IDirect3DVertexBuffer9Impl *buffer = impl_from_IDirect3DVertexBuffer9(iface);
Henri Verbeet15491802010-09-01 18:41:04 +020072 ULONG refcount = InterlockedDecrement(&buffer->ref);
73
74 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
75
76 if (!refcount)
77 {
78 IDirect3DDevice9Ex *device = buffer->parentDevice;
79
80 wined3d_mutex_lock();
Henri Verbeeta27ee752011-03-03 21:49:09 +010081 wined3d_buffer_decref(buffer->wineD3DVertexBuffer);
Henri Verbeet15491802010-09-01 18:41:04 +020082 wined3d_mutex_unlock();
83
84 /* Release the device last, as it may cause the device to be destroyed. */
85 IDirect3DDevice9Ex_Release(device);
86 }
87
88 return refcount;
89}
90
Michael Stefaniuc17eccaf2011-07-06 13:29:02 +020091static HRESULT WINAPI d3d9_vertexbuffer_GetDevice(IDirect3DVertexBuffer9 *iface,
92 IDirect3DDevice9 **device)
Henri Verbeet15491802010-09-01 18:41:04 +020093{
Michael Stefaniuc17eccaf2011-07-06 13:29:02 +020094 IDirect3DVertexBuffer9Impl *buffer = impl_from_IDirect3DVertexBuffer9(iface);
95
Henri Verbeet15491802010-09-01 18:41:04 +020096 TRACE("iface %p, device %p.\n", iface, device);
97
Michael Stefaniuc17eccaf2011-07-06 13:29:02 +020098 *device = (IDirect3DDevice9 *)buffer->parentDevice;
Henri Verbeet15491802010-09-01 18:41:04 +020099 IDirect3DDevice9_AddRef(*device);
100
101 TRACE("Returning device %p.\n", *device);
102
103 return D3D_OK;
104}
105
106static HRESULT WINAPI d3d9_vertexbuffer_SetPrivateData(IDirect3DVertexBuffer9 *iface,
107 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
108{
Henri Verbeet469eba22011-06-16 22:38:26 +0200109 IDirect3DVertexBuffer9Impl *buffer = impl_from_IDirect3DVertexBuffer9(iface);
110 struct wined3d_resource *resource;
Henri Verbeet15491802010-09-01 18:41:04 +0200111 HRESULT hr;
112
113 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
114 iface, debugstr_guid(guid), data, data_size, flags);
115
116 wined3d_mutex_lock();
Henri Verbeet469eba22011-06-16 22:38:26 +0200117 resource = wined3d_buffer_get_resource(buffer->wineD3DVertexBuffer);
118 hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
Henri Verbeet15491802010-09-01 18:41:04 +0200119 wined3d_mutex_unlock();
120
121 return hr;
122}
123
124static HRESULT WINAPI d3d9_vertexbuffer_GetPrivateData(IDirect3DVertexBuffer9 *iface,
125 REFGUID guid, void *data, DWORD *data_size)
126{
Henri Verbeet469eba22011-06-16 22:38:26 +0200127 IDirect3DVertexBuffer9Impl *buffer = impl_from_IDirect3DVertexBuffer9(iface);
128 struct wined3d_resource *resource;
Henri Verbeet15491802010-09-01 18:41:04 +0200129 HRESULT hr;
130
131 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
132 iface, debugstr_guid(guid), data, data_size);
133
134 wined3d_mutex_lock();
Henri Verbeet469eba22011-06-16 22:38:26 +0200135 resource = wined3d_buffer_get_resource(buffer->wineD3DVertexBuffer);
136 hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
Henri Verbeet15491802010-09-01 18:41:04 +0200137 wined3d_mutex_unlock();
138
139 return hr;
140}
141
142static HRESULT WINAPI d3d9_vertexbuffer_FreePrivateData(IDirect3DVertexBuffer9 *iface, REFGUID guid)
143{
Henri Verbeet469eba22011-06-16 22:38:26 +0200144 IDirect3DVertexBuffer9Impl *buffer = impl_from_IDirect3DVertexBuffer9(iface);
145 struct wined3d_resource *resource;
Henri Verbeet15491802010-09-01 18:41:04 +0200146 HRESULT hr;
147
148 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
149
150 wined3d_mutex_lock();
Henri Verbeet469eba22011-06-16 22:38:26 +0200151 resource = wined3d_buffer_get_resource(buffer->wineD3DVertexBuffer);
152 hr = wined3d_resource_free_private_data(resource, guid);
Henri Verbeet15491802010-09-01 18:41:04 +0200153 wined3d_mutex_unlock();
154
155 return hr;
156}
157
158static DWORD WINAPI d3d9_vertexbuffer_SetPriority(IDirect3DVertexBuffer9 *iface, DWORD priority)
159{
Michael Stefaniuc17eccaf2011-07-06 13:29:02 +0200160 IDirect3DVertexBuffer9Impl *buffer = impl_from_IDirect3DVertexBuffer9(iface);
Henri Verbeet15491802010-09-01 18:41:04 +0200161 DWORD previous;
162
163 TRACE("iface %p, priority %u.\n", iface, priority);
164
165 wined3d_mutex_lock();
Michael Stefaniuc17eccaf2011-07-06 13:29:02 +0200166 previous = wined3d_buffer_set_priority(buffer->wineD3DVertexBuffer, priority);
Henri Verbeet15491802010-09-01 18:41:04 +0200167 wined3d_mutex_unlock();
168
169 return previous;
170}
171
172static DWORD WINAPI d3d9_vertexbuffer_GetPriority(IDirect3DVertexBuffer9 *iface)
173{
Michael Stefaniuc17eccaf2011-07-06 13:29:02 +0200174 IDirect3DVertexBuffer9Impl *buffer = impl_from_IDirect3DVertexBuffer9(iface);
Henri Verbeet15491802010-09-01 18:41:04 +0200175 DWORD priority;
176
177 TRACE("iface %p.\n", iface);
178
179 wined3d_mutex_lock();
Michael Stefaniuc17eccaf2011-07-06 13:29:02 +0200180 priority = wined3d_buffer_get_priority(buffer->wineD3DVertexBuffer);
Henri Verbeet15491802010-09-01 18:41:04 +0200181 wined3d_mutex_unlock();
182
183 return priority;
184}
185
186static void WINAPI d3d9_vertexbuffer_PreLoad(IDirect3DVertexBuffer9 *iface)
187{
Michael Stefaniuc17eccaf2011-07-06 13:29:02 +0200188 IDirect3DVertexBuffer9Impl *buffer = impl_from_IDirect3DVertexBuffer9(iface);
189
Henri Verbeet15491802010-09-01 18:41:04 +0200190 TRACE("iface %p.\n", iface);
191
192 wined3d_mutex_lock();
Michael Stefaniuc17eccaf2011-07-06 13:29:02 +0200193 wined3d_buffer_preload(buffer->wineD3DVertexBuffer);
Henri Verbeet15491802010-09-01 18:41:04 +0200194 wined3d_mutex_unlock();
195}
196
197static D3DRESOURCETYPE WINAPI d3d9_vertexbuffer_GetType(IDirect3DVertexBuffer9 *iface)
198{
199 TRACE("iface %p.\n", iface);
200
201 return D3DRTYPE_VERTEXBUFFER;
202}
203
Michael Stefaniuc17eccaf2011-07-06 13:29:02 +0200204static HRESULT WINAPI d3d9_vertexbuffer_Lock(IDirect3DVertexBuffer9 *iface, UINT offset, UINT size,
205 void **data, DWORD flags)
Henri Verbeet15491802010-09-01 18:41:04 +0200206{
Michael Stefaniuc17eccaf2011-07-06 13:29:02 +0200207 IDirect3DVertexBuffer9Impl *buffer = impl_from_IDirect3DVertexBuffer9(iface);
Henri Verbeet15491802010-09-01 18:41:04 +0200208 HRESULT hr;
209
210 TRACE("iface %p, offset %u, size %u, data %p, flags %#x.\n",
211 iface, offset, size, data, flags);
212
213 wined3d_mutex_lock();
Michael Stefaniuc17eccaf2011-07-06 13:29:02 +0200214 hr = wined3d_buffer_map(buffer->wineD3DVertexBuffer, offset, size, (BYTE **)data, flags);
Henri Verbeet15491802010-09-01 18:41:04 +0200215 wined3d_mutex_unlock();
216
217 return hr;
218}
219
220static HRESULT WINAPI d3d9_vertexbuffer_Unlock(IDirect3DVertexBuffer9 *iface)
221{
Michael Stefaniuc17eccaf2011-07-06 13:29:02 +0200222 IDirect3DVertexBuffer9Impl *buffer = impl_from_IDirect3DVertexBuffer9(iface);
223
Henri Verbeet15491802010-09-01 18:41:04 +0200224 TRACE("iface %p.\n", iface);
225
226 wined3d_mutex_lock();
Michael Stefaniuc17eccaf2011-07-06 13:29:02 +0200227 wined3d_buffer_unmap(buffer->wineD3DVertexBuffer);
Henri Verbeet15491802010-09-01 18:41:04 +0200228 wined3d_mutex_unlock();
229
Henri Verbeet70f4e662010-10-15 14:35:12 +0200230 return D3D_OK;
Henri Verbeet15491802010-09-01 18:41:04 +0200231}
232
Michael Stefaniuc17eccaf2011-07-06 13:29:02 +0200233static HRESULT WINAPI d3d9_vertexbuffer_GetDesc(IDirect3DVertexBuffer9 *iface,
234 D3DVERTEXBUFFER_DESC *desc)
Henri Verbeet15491802010-09-01 18:41:04 +0200235{
Michael Stefaniuc17eccaf2011-07-06 13:29:02 +0200236 IDirect3DVertexBuffer9Impl *buffer = impl_from_IDirect3DVertexBuffer9(iface);
Henri Verbeet756fdb72011-03-08 19:41:05 +0100237 struct wined3d_resource_desc wined3d_desc;
Henri Verbeetadb1e102011-03-10 19:07:10 +0100238 struct wined3d_resource *wined3d_resource;
Henri Verbeet15491802010-09-01 18:41:04 +0200239
240 TRACE("iface %p, desc %p.\n", iface, desc);
241
242 wined3d_mutex_lock();
Henri Verbeetadb1e102011-03-10 19:07:10 +0100243 wined3d_resource = wined3d_buffer_get_resource(buffer->wineD3DVertexBuffer);
244 wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
Henri Verbeet15491802010-09-01 18:41:04 +0200245 wined3d_mutex_unlock();
246
Henri Verbeetfd7c1cb2010-09-14 13:38:38 +0200247 desc->Format = D3DFMT_VERTEXDATA;
Henri Verbeet756fdb72011-03-08 19:41:05 +0100248 desc->Usage = wined3d_desc.usage;
249 desc->Pool = wined3d_desc.pool;
250 desc->Size = wined3d_desc.size;
Henri Verbeetfd7c1cb2010-09-14 13:38:38 +0200251 desc->Type = D3DRTYPE_VERTEXBUFFER;
252 desc->FVF = buffer->fvf;
Henri Verbeet15491802010-09-01 18:41:04 +0200253
Henri Verbeetfd7c1cb2010-09-14 13:38:38 +0200254 return D3D_OK;
Henri Verbeet15491802010-09-01 18:41:04 +0200255}
256
257static const IDirect3DVertexBuffer9Vtbl d3d9_vertexbuffer_vtbl =
258{
259 /* IUnknown */
260 d3d9_vertexbuffer_QueryInterface,
261 d3d9_vertexbuffer_AddRef,
262 d3d9_vertexbuffer_Release,
263 /* IDirect3DResource9 */
264 d3d9_vertexbuffer_GetDevice,
265 d3d9_vertexbuffer_SetPrivateData,
266 d3d9_vertexbuffer_GetPrivateData,
267 d3d9_vertexbuffer_FreePrivateData,
268 d3d9_vertexbuffer_SetPriority,
269 d3d9_vertexbuffer_GetPriority,
270 d3d9_vertexbuffer_PreLoad,
271 d3d9_vertexbuffer_GetType,
272 /* IDirect3DVertexBuffer9 */
273 d3d9_vertexbuffer_Lock,
274 d3d9_vertexbuffer_Unlock,
275 d3d9_vertexbuffer_GetDesc,
276};
277
278static void STDMETHODCALLTYPE d3d9_vertexbuffer_wined3d_object_destroyed(void *parent)
279{
280 HeapFree(GetProcessHeap(), 0, parent);
281}
282
283static const struct wined3d_parent_ops d3d9_vertexbuffer_wined3d_parent_ops =
284{
285 d3d9_vertexbuffer_wined3d_object_destroyed,
286};
287
288HRESULT vertexbuffer_init(IDirect3DVertexBuffer9Impl *buffer, IDirect3DDevice9Impl *device,
289 UINT size, UINT usage, DWORD fvf, D3DPOOL pool)
290{
291 HRESULT hr;
292
Michael Stefaniuc17eccaf2011-07-06 13:29:02 +0200293 buffer->IDirect3DVertexBuffer9_iface.lpVtbl = &d3d9_vertexbuffer_vtbl;
Henri Verbeet15491802010-09-01 18:41:04 +0200294 buffer->ref = 1;
295 buffer->fvf = fvf;
296
297 wined3d_mutex_lock();
Henri Verbeet8d4ca1f2011-05-16 23:01:22 +0200298 hr = wined3d_buffer_create_vb(device->wined3d_device, size, usage & WINED3DUSAGE_MASK,
Henri Verbeet15491802010-09-01 18:41:04 +0200299 (WINED3DPOOL)pool, buffer, &d3d9_vertexbuffer_wined3d_parent_ops, &buffer->wineD3DVertexBuffer);
300 wined3d_mutex_unlock();
301 if (FAILED(hr))
302 {
303 WARN("Failed to create wined3d buffer, hr %#x.\n", hr);
304 return hr;
305 }
306
Michael Stefaniucd5739cd2011-04-24 21:34:30 +0200307 buffer->parentDevice = &device->IDirect3DDevice9Ex_iface;
Henri Verbeet15491802010-09-01 18:41:04 +0200308 IDirect3DDevice9Ex_AddRef(buffer->parentDevice);
309
310 return D3D_OK;
311}
312
Michael Stefaniuc2b3a3642011-07-06 13:27:01 +0200313IDirect3DVertexBuffer9Impl *unsafe_impl_from_IDirect3DVertexBuffer9(IDirect3DVertexBuffer9 *iface)
314{
315 if (!iface)
316 return NULL;
317 assert(iface->lpVtbl == &d3d9_vertexbuffer_vtbl);
318
319 return impl_from_IDirect3DVertexBuffer9(iface);
320}
321
Henri Verbeeta5ee9f12011-06-16 22:38:27 +0200322static inline IDirect3DIndexBuffer9Impl *impl_from_IDirect3DIndexBuffer9(IDirect3DIndexBuffer9 *iface)
323{
Michael Stefaniucdb1dd902011-07-05 12:02:25 +0200324 return CONTAINING_RECORD(iface, IDirect3DIndexBuffer9Impl, IDirect3DIndexBuffer9_iface);
Henri Verbeeta5ee9f12011-06-16 22:38:27 +0200325}
326
Henri Verbeet15491802010-09-01 18:41:04 +0200327static HRESULT WINAPI d3d9_indexbuffer_QueryInterface(IDirect3DIndexBuffer9 *iface, REFIID riid, void **object)
328{
329 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
330
331 if (IsEqualGUID(riid, &IID_IDirect3DIndexBuffer9)
332 || IsEqualGUID(riid, &IID_IDirect3DResource9)
333 || IsEqualGUID(riid, &IID_IUnknown))
334 {
335 IDirect3DIndexBuffer9_AddRef(iface);
336 *object = iface;
337 return S_OK;
338 }
339
340 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
341
342 *object = NULL;
343 return E_NOINTERFACE;
344}
345
346static ULONG WINAPI d3d9_indexbuffer_AddRef(IDirect3DIndexBuffer9 *iface)
347{
Michael Stefaniucdb1dd902011-07-05 12:02:25 +0200348 IDirect3DIndexBuffer9Impl *buffer = impl_from_IDirect3DIndexBuffer9(iface);
Henri Verbeet15491802010-09-01 18:41:04 +0200349 ULONG refcount = InterlockedIncrement(&buffer->ref);
350
351 TRACE("%p increasing refcount to %u.\n", iface, refcount);
352
353 if (refcount == 1)
354 {
355 IDirect3DDevice9Ex_AddRef(buffer->parentDevice);
356 wined3d_mutex_lock();
Henri Verbeeta27ee752011-03-03 21:49:09 +0100357 wined3d_buffer_incref(buffer->wineD3DIndexBuffer);
Henri Verbeet15491802010-09-01 18:41:04 +0200358 wined3d_mutex_unlock();
359 }
360
361 return refcount;
362}
363
364static ULONG WINAPI d3d9_indexbuffer_Release(IDirect3DIndexBuffer9 *iface)
365{
Michael Stefaniucdb1dd902011-07-05 12:02:25 +0200366 IDirect3DIndexBuffer9Impl *buffer = impl_from_IDirect3DIndexBuffer9(iface);
Henri Verbeet15491802010-09-01 18:41:04 +0200367 ULONG refcount = InterlockedDecrement(&buffer->ref);
368
369 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
370
371 if (!refcount)
372 {
373 IDirect3DDevice9Ex *device = buffer->parentDevice;
374
375 wined3d_mutex_lock();
Henri Verbeeta27ee752011-03-03 21:49:09 +0100376 wined3d_buffer_decref(buffer->wineD3DIndexBuffer);
Henri Verbeet15491802010-09-01 18:41:04 +0200377 wined3d_mutex_unlock();
378
379 /* Release the device last, as it may cause the device to be destroyed. */
380 IDirect3DDevice9Ex_Release(device);
381 }
382
383 return refcount;
384}
385
Michael Stefaniucdb1dd902011-07-05 12:02:25 +0200386static HRESULT WINAPI d3d9_indexbuffer_GetDevice(IDirect3DIndexBuffer9 *iface,
387 IDirect3DDevice9 **device)
Henri Verbeet15491802010-09-01 18:41:04 +0200388{
Michael Stefaniucdb1dd902011-07-05 12:02:25 +0200389 IDirect3DIndexBuffer9Impl *buffer = impl_from_IDirect3DIndexBuffer9(iface);
390
Henri Verbeet15491802010-09-01 18:41:04 +0200391 TRACE("iface %p, device %p.\n", iface, device);
392
Michael Stefaniucdb1dd902011-07-05 12:02:25 +0200393 *device = (IDirect3DDevice9 *)buffer->parentDevice;
Henri Verbeet15491802010-09-01 18:41:04 +0200394 IDirect3DDevice9_AddRef(*device);
395
396 TRACE("Returning device %p.\n", *device);
397
398 return D3D_OK;
399}
400
401static HRESULT WINAPI d3d9_indexbuffer_SetPrivateData(IDirect3DIndexBuffer9 *iface,
402 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
403{
Henri Verbeeta5ee9f12011-06-16 22:38:27 +0200404 IDirect3DIndexBuffer9Impl *buffer = impl_from_IDirect3DIndexBuffer9(iface);
405 struct wined3d_resource *resource;
Henri Verbeet15491802010-09-01 18:41:04 +0200406 HRESULT hr;
407
408 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
409 iface, debugstr_guid(guid), data, data_size, flags);
410
411 wined3d_mutex_lock();
Henri Verbeeta5ee9f12011-06-16 22:38:27 +0200412 resource = wined3d_buffer_get_resource(buffer->wineD3DIndexBuffer);
413 hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
Henri Verbeet15491802010-09-01 18:41:04 +0200414 wined3d_mutex_unlock();
415
416 return hr;
417}
418
419static HRESULT WINAPI d3d9_indexbuffer_GetPrivateData(IDirect3DIndexBuffer9 *iface,
420 REFGUID guid, void *data, DWORD *data_size)
421{
Henri Verbeeta5ee9f12011-06-16 22:38:27 +0200422 IDirect3DIndexBuffer9Impl *buffer = impl_from_IDirect3DIndexBuffer9(iface);
423 struct wined3d_resource *resource;
Henri Verbeet15491802010-09-01 18:41:04 +0200424 HRESULT hr;
425
426 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
427 iface, debugstr_guid(guid), data, data_size);
428
429 wined3d_mutex_lock();
Henri Verbeeta5ee9f12011-06-16 22:38:27 +0200430 resource = wined3d_buffer_get_resource(buffer->wineD3DIndexBuffer);
431 hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
Henri Verbeet15491802010-09-01 18:41:04 +0200432 wined3d_mutex_unlock();
433
434 return hr;
435}
436
437static HRESULT WINAPI d3d9_indexbuffer_FreePrivateData(IDirect3DIndexBuffer9 *iface, REFGUID guid)
438{
Henri Verbeeta5ee9f12011-06-16 22:38:27 +0200439 IDirect3DIndexBuffer9Impl *buffer = impl_from_IDirect3DIndexBuffer9(iface);
440 struct wined3d_resource *resource;
Henri Verbeet15491802010-09-01 18:41:04 +0200441 HRESULT hr;
442
443 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
444
445 wined3d_mutex_lock();
Henri Verbeeta5ee9f12011-06-16 22:38:27 +0200446 resource = wined3d_buffer_get_resource(buffer->wineD3DIndexBuffer);
447 hr = wined3d_resource_free_private_data(resource, guid);
Henri Verbeet15491802010-09-01 18:41:04 +0200448 wined3d_mutex_unlock();
449
450 return hr;
451}
452
453static DWORD WINAPI d3d9_indexbuffer_SetPriority(IDirect3DIndexBuffer9 *iface, DWORD priority)
454{
Michael Stefaniucdb1dd902011-07-05 12:02:25 +0200455 IDirect3DIndexBuffer9Impl *buffer = impl_from_IDirect3DIndexBuffer9(iface);
Henri Verbeet15491802010-09-01 18:41:04 +0200456 DWORD previous;
457
458 TRACE("iface %p, priority %u.\n", iface, priority);
459
460 wined3d_mutex_lock();
Michael Stefaniucdb1dd902011-07-05 12:02:25 +0200461 previous = wined3d_buffer_set_priority(buffer->wineD3DIndexBuffer, priority);
Henri Verbeet15491802010-09-01 18:41:04 +0200462 wined3d_mutex_unlock();
463
464 return previous;
465}
466
467static DWORD WINAPI d3d9_indexbuffer_GetPriority(IDirect3DIndexBuffer9 *iface)
468{
Michael Stefaniucdb1dd902011-07-05 12:02:25 +0200469 IDirect3DIndexBuffer9Impl *buffer = impl_from_IDirect3DIndexBuffer9(iface);
Henri Verbeet15491802010-09-01 18:41:04 +0200470 DWORD priority;
471
472 TRACE("iface %p.\n", iface);
473
474 wined3d_mutex_lock();
Michael Stefaniucdb1dd902011-07-05 12:02:25 +0200475 priority = wined3d_buffer_get_priority(buffer->wineD3DIndexBuffer);
Henri Verbeet15491802010-09-01 18:41:04 +0200476 wined3d_mutex_unlock();
477
478 return priority;
479}
480
481static void WINAPI d3d9_indexbuffer_PreLoad(IDirect3DIndexBuffer9 *iface)
482{
Michael Stefaniucdb1dd902011-07-05 12:02:25 +0200483 IDirect3DIndexBuffer9Impl *buffer = impl_from_IDirect3DIndexBuffer9(iface);
484
Henri Verbeet15491802010-09-01 18:41:04 +0200485 TRACE("iface %p.\n", iface);
486
487 wined3d_mutex_lock();
Michael Stefaniucdb1dd902011-07-05 12:02:25 +0200488 wined3d_buffer_preload(buffer->wineD3DIndexBuffer);
Henri Verbeet15491802010-09-01 18:41:04 +0200489 wined3d_mutex_unlock();
490}
491
492static D3DRESOURCETYPE WINAPI d3d9_indexbuffer_GetType(IDirect3DIndexBuffer9 *iface)
493{
494 TRACE("iface %p.\n", iface);
495
496 return D3DRTYPE_INDEXBUFFER;
497}
498
499static HRESULT WINAPI d3d9_indexbuffer_Lock(IDirect3DIndexBuffer9 *iface,
500 UINT offset, UINT size, void **data, DWORD flags)
501{
Michael Stefaniucdb1dd902011-07-05 12:02:25 +0200502 IDirect3DIndexBuffer9Impl *buffer = impl_from_IDirect3DIndexBuffer9(iface);
Henri Verbeet15491802010-09-01 18:41:04 +0200503 HRESULT hr;
504
505 TRACE("iface %p, offset %u, size %u, data %p, flags %#x.\n",
506 iface, offset, size, data, flags);
507
508 wined3d_mutex_lock();
Michael Stefaniucdb1dd902011-07-05 12:02:25 +0200509 hr = wined3d_buffer_map(buffer->wineD3DIndexBuffer, offset, size, (BYTE **)data, flags);
Henri Verbeet15491802010-09-01 18:41:04 +0200510 wined3d_mutex_unlock();
511
512 return hr;
513}
514
515static HRESULT WINAPI d3d9_indexbuffer_Unlock(IDirect3DIndexBuffer9 *iface)
516{
Michael Stefaniucdb1dd902011-07-05 12:02:25 +0200517 IDirect3DIndexBuffer9Impl *buffer = impl_from_IDirect3DIndexBuffer9(iface);
518
Henri Verbeet15491802010-09-01 18:41:04 +0200519 TRACE("iface %p.\n", iface);
520
521 wined3d_mutex_lock();
Michael Stefaniucdb1dd902011-07-05 12:02:25 +0200522 wined3d_buffer_unmap(buffer->wineD3DIndexBuffer);
Henri Verbeet15491802010-09-01 18:41:04 +0200523 wined3d_mutex_unlock();
524
Henri Verbeet70f4e662010-10-15 14:35:12 +0200525 return D3D_OK;
Henri Verbeet15491802010-09-01 18:41:04 +0200526}
527
Michael Stefaniucdb1dd902011-07-05 12:02:25 +0200528static HRESULT WINAPI d3d9_indexbuffer_GetDesc(IDirect3DIndexBuffer9 *iface,
529 D3DINDEXBUFFER_DESC *desc)
Henri Verbeet15491802010-09-01 18:41:04 +0200530{
Michael Stefaniucdb1dd902011-07-05 12:02:25 +0200531 IDirect3DIndexBuffer9Impl *buffer = impl_from_IDirect3DIndexBuffer9(iface);
Henri Verbeet756fdb72011-03-08 19:41:05 +0100532 struct wined3d_resource_desc wined3d_desc;
Henri Verbeetadb1e102011-03-10 19:07:10 +0100533 struct wined3d_resource *wined3d_resource;
Henri Verbeet15491802010-09-01 18:41:04 +0200534
535 TRACE("iface %p, desc %p.\n", iface, desc);
536
537 wined3d_mutex_lock();
Henri Verbeetadb1e102011-03-10 19:07:10 +0100538 wined3d_resource = wined3d_buffer_get_resource(buffer->wineD3DIndexBuffer);
539 wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
Henri Verbeet15491802010-09-01 18:41:04 +0200540 wined3d_mutex_unlock();
541
Henri Verbeetfd7c1cb2010-09-14 13:38:38 +0200542 desc->Format = d3dformat_from_wined3dformat(buffer->format);
Henri Verbeet756fdb72011-03-08 19:41:05 +0100543 desc->Usage = wined3d_desc.usage;
544 desc->Pool = wined3d_desc.pool;
545 desc->Size = wined3d_desc.size;
Henri Verbeetfd7c1cb2010-09-14 13:38:38 +0200546 desc->Type = D3DRTYPE_INDEXBUFFER;
Henri Verbeet15491802010-09-01 18:41:04 +0200547
Henri Verbeetfd7c1cb2010-09-14 13:38:38 +0200548 return D3D_OK;
Henri Verbeet15491802010-09-01 18:41:04 +0200549}
550
551static const IDirect3DIndexBuffer9Vtbl d3d9_indexbuffer_vtbl =
552{
553 /* IUnknown */
554 d3d9_indexbuffer_QueryInterface,
555 d3d9_indexbuffer_AddRef,
556 d3d9_indexbuffer_Release,
557 /* IDirect3DResource9 */
558 d3d9_indexbuffer_GetDevice,
559 d3d9_indexbuffer_SetPrivateData,
560 d3d9_indexbuffer_GetPrivateData,
561 d3d9_indexbuffer_FreePrivateData,
562 d3d9_indexbuffer_SetPriority,
563 d3d9_indexbuffer_GetPriority,
564 d3d9_indexbuffer_PreLoad,
565 d3d9_indexbuffer_GetType,
566 /* IDirect3DIndexBuffer9 */
567 d3d9_indexbuffer_Lock,
568 d3d9_indexbuffer_Unlock,
569 d3d9_indexbuffer_GetDesc,
570};
571
572static void STDMETHODCALLTYPE d3d9_indexbuffer_wined3d_object_destroyed(void *parent)
573{
574 HeapFree(GetProcessHeap(), 0, parent);
575}
576
577static const struct wined3d_parent_ops d3d9_indexbuffer_wined3d_parent_ops =
578{
579 d3d9_indexbuffer_wined3d_object_destroyed,
580};
581
582HRESULT indexbuffer_init(IDirect3DIndexBuffer9Impl *buffer, IDirect3DDevice9Impl *device,
583 UINT size, DWORD usage, D3DFORMAT format, D3DPOOL pool)
584{
585 HRESULT hr;
586
Michael Stefaniucdb1dd902011-07-05 12:02:25 +0200587 buffer->IDirect3DIndexBuffer9_iface.lpVtbl = &d3d9_indexbuffer_vtbl;
Henri Verbeet15491802010-09-01 18:41:04 +0200588 buffer->ref = 1;
589 buffer->format = wined3dformat_from_d3dformat(format);
590
591 wined3d_mutex_lock();
Henri Verbeet8d4ca1f2011-05-16 23:01:22 +0200592 hr = wined3d_buffer_create_ib(device->wined3d_device, size, usage & WINED3DUSAGE_MASK,
Henri Verbeet15491802010-09-01 18:41:04 +0200593 (WINED3DPOOL)pool, buffer, &d3d9_indexbuffer_wined3d_parent_ops, &buffer->wineD3DIndexBuffer);
594 wined3d_mutex_unlock();
595 if (FAILED(hr))
596 {
597 WARN("Failed to create wined3d buffer, hr %#x.\n", hr);
598 return hr;
599 }
600
Michael Stefaniucd5739cd2011-04-24 21:34:30 +0200601 buffer->parentDevice = &device->IDirect3DDevice9Ex_iface;
Henri Verbeet15491802010-09-01 18:41:04 +0200602 IDirect3DDevice9Ex_AddRef(buffer->parentDevice);
603
604 return D3D_OK;
605}
Michael Stefaniuc875d6902011-07-05 12:01:01 +0200606
607IDirect3DIndexBuffer9Impl *unsafe_impl_from_IDirect3DIndexBuffer9(IDirect3DIndexBuffer9 *iface)
608{
609 if (!iface)
610 return NULL;
611 assert(iface->lpVtbl == &d3d9_indexbuffer_vtbl);
612
613 return impl_from_IDirect3DIndexBuffer9(iface);
614}