2 * Copyright 2002-2004 Jason Edmeades
3 * Copyright 2002-2004 Raphael Junqueira
4 * Copyright 2005 Oliver Stieber
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.
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.
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
22 #include "d3d9_private.h"
24 WINE_DEFAULT_DEBUG_CHANNEL(d3d9
);
26 static inline struct d3d9_vertexbuffer
*impl_from_IDirect3DVertexBuffer9(IDirect3DVertexBuffer9
*iface
)
28 return CONTAINING_RECORD(iface
, struct d3d9_vertexbuffer
, IDirect3DVertexBuffer9_iface
);
31 static HRESULT WINAPI
d3d9_vertexbuffer_QueryInterface(IDirect3DVertexBuffer9
*iface
, REFIID riid
, void **out
)
33 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
35 if (IsEqualGUID(riid
, &IID_IDirect3DVertexBuffer9
)
36 || IsEqualGUID(riid
, &IID_IDirect3DResource9
)
37 || IsEqualGUID(riid
, &IID_IUnknown
))
39 IDirect3DVertexBuffer9_AddRef(iface
);
44 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
50 static ULONG WINAPI
d3d9_vertexbuffer_AddRef(IDirect3DVertexBuffer9
*iface
)
52 struct d3d9_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer9(iface
);
53 ULONG refcount
= InterlockedIncrement(&buffer
->refcount
);
55 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
59 IDirect3DDevice9Ex_AddRef(buffer
->parent_device
);
61 wined3d_buffer_incref(buffer
->wined3d_buffer
);
62 wined3d_mutex_unlock();
68 static ULONG WINAPI
d3d9_vertexbuffer_Release(IDirect3DVertexBuffer9
*iface
)
70 struct d3d9_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer9(iface
);
71 ULONG refcount
= InterlockedDecrement(&buffer
->refcount
);
73 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
77 IDirect3DDevice9Ex
*device
= buffer
->parent_device
;
80 wined3d_buffer_decref(buffer
->wined3d_buffer
);
81 wined3d_mutex_unlock();
83 /* Release the device last, as it may cause the device to be destroyed. */
84 IDirect3DDevice9Ex_Release(device
);
90 static HRESULT WINAPI
d3d9_vertexbuffer_GetDevice(IDirect3DVertexBuffer9
*iface
, IDirect3DDevice9
**device
)
92 struct d3d9_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer9(iface
);
94 TRACE("iface %p, device %p.\n", iface
, device
);
96 *device
= (IDirect3DDevice9
*)buffer
->parent_device
;
97 IDirect3DDevice9_AddRef(*device
);
99 TRACE("Returning device %p.\n", *device
);
104 static HRESULT WINAPI
d3d9_vertexbuffer_SetPrivateData(IDirect3DVertexBuffer9
*iface
,
105 REFGUID guid
, const void *data
, DWORD data_size
, DWORD flags
)
107 struct d3d9_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer9(iface
);
108 struct wined3d_resource
*resource
;
111 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
112 iface
, debugstr_guid(guid
), data
, data_size
, flags
);
114 wined3d_mutex_lock();
115 resource
= wined3d_buffer_get_resource(buffer
->wined3d_buffer
);
116 hr
= wined3d_resource_set_private_data(resource
, guid
, data
, data_size
, flags
);
117 wined3d_mutex_unlock();
122 static HRESULT WINAPI
d3d9_vertexbuffer_GetPrivateData(IDirect3DVertexBuffer9
*iface
,
123 REFGUID guid
, void *data
, DWORD
*data_size
)
125 struct d3d9_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer9(iface
);
126 struct wined3d_resource
*resource
;
129 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
130 iface
, debugstr_guid(guid
), data
, data_size
);
132 wined3d_mutex_lock();
133 resource
= wined3d_buffer_get_resource(buffer
->wined3d_buffer
);
134 hr
= wined3d_resource_get_private_data(resource
, guid
, data
, data_size
);
135 wined3d_mutex_unlock();
140 static HRESULT WINAPI
d3d9_vertexbuffer_FreePrivateData(IDirect3DVertexBuffer9
*iface
, REFGUID guid
)
142 struct d3d9_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer9(iface
);
143 struct wined3d_resource
*resource
;
146 TRACE("iface %p, guid %s.\n", iface
, debugstr_guid(guid
));
148 wined3d_mutex_lock();
149 resource
= wined3d_buffer_get_resource(buffer
->wined3d_buffer
);
150 hr
= wined3d_resource_free_private_data(resource
, guid
);
151 wined3d_mutex_unlock();
156 static DWORD WINAPI
d3d9_vertexbuffer_SetPriority(IDirect3DVertexBuffer9
*iface
, DWORD priority
)
158 struct d3d9_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer9(iface
);
161 TRACE("iface %p, priority %u.\n", iface
, priority
);
163 wined3d_mutex_lock();
164 previous
= wined3d_buffer_set_priority(buffer
->wined3d_buffer
, priority
);
165 wined3d_mutex_unlock();
170 static DWORD WINAPI
d3d9_vertexbuffer_GetPriority(IDirect3DVertexBuffer9
*iface
)
172 struct d3d9_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer9(iface
);
175 TRACE("iface %p.\n", iface
);
177 wined3d_mutex_lock();
178 priority
= wined3d_buffer_get_priority(buffer
->wined3d_buffer
);
179 wined3d_mutex_unlock();
184 static void WINAPI
d3d9_vertexbuffer_PreLoad(IDirect3DVertexBuffer9
*iface
)
186 struct d3d9_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer9(iface
);
188 TRACE("iface %p.\n", iface
);
190 wined3d_mutex_lock();
191 wined3d_buffer_preload(buffer
->wined3d_buffer
);
192 wined3d_mutex_unlock();
195 static D3DRESOURCETYPE WINAPI
d3d9_vertexbuffer_GetType(IDirect3DVertexBuffer9
*iface
)
197 TRACE("iface %p.\n", iface
);
199 return D3DRTYPE_VERTEXBUFFER
;
202 static HRESULT WINAPI
d3d9_vertexbuffer_Lock(IDirect3DVertexBuffer9
*iface
, UINT offset
, UINT size
,
203 void **data
, DWORD flags
)
205 struct d3d9_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer9(iface
);
208 TRACE("iface %p, offset %u, size %u, data %p, flags %#x.\n",
209 iface
, offset
, size
, data
, flags
);
211 wined3d_mutex_lock();
212 hr
= wined3d_buffer_map(buffer
->wined3d_buffer
, offset
, size
, (BYTE
**)data
, flags
);
213 wined3d_mutex_unlock();
218 static HRESULT WINAPI
d3d9_vertexbuffer_Unlock(IDirect3DVertexBuffer9
*iface
)
220 struct d3d9_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer9(iface
);
222 TRACE("iface %p.\n", iface
);
224 wined3d_mutex_lock();
225 wined3d_buffer_unmap(buffer
->wined3d_buffer
);
226 wined3d_mutex_unlock();
231 static HRESULT WINAPI
d3d9_vertexbuffer_GetDesc(IDirect3DVertexBuffer9
*iface
,
232 D3DVERTEXBUFFER_DESC
*desc
)
234 struct d3d9_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer9(iface
);
235 struct wined3d_resource_desc wined3d_desc
;
236 struct wined3d_resource
*wined3d_resource
;
238 TRACE("iface %p, desc %p.\n", iface
, desc
);
240 wined3d_mutex_lock();
241 wined3d_resource
= wined3d_buffer_get_resource(buffer
->wined3d_buffer
);
242 wined3d_resource_get_desc(wined3d_resource
, &wined3d_desc
);
243 wined3d_mutex_unlock();
245 desc
->Format
= D3DFMT_VERTEXDATA
;
246 desc
->Usage
= wined3d_desc
.usage
& WINED3DUSAGE_MASK
;
247 desc
->Pool
= wined3d_desc
.pool
;
248 desc
->Size
= wined3d_desc
.size
;
249 desc
->Type
= D3DRTYPE_VERTEXBUFFER
;
250 desc
->FVF
= buffer
->fvf
;
255 static const IDirect3DVertexBuffer9Vtbl d3d9_vertexbuffer_vtbl
=
258 d3d9_vertexbuffer_QueryInterface
,
259 d3d9_vertexbuffer_AddRef
,
260 d3d9_vertexbuffer_Release
,
261 /* IDirect3DResource9 */
262 d3d9_vertexbuffer_GetDevice
,
263 d3d9_vertexbuffer_SetPrivateData
,
264 d3d9_vertexbuffer_GetPrivateData
,
265 d3d9_vertexbuffer_FreePrivateData
,
266 d3d9_vertexbuffer_SetPriority
,
267 d3d9_vertexbuffer_GetPriority
,
268 d3d9_vertexbuffer_PreLoad
,
269 d3d9_vertexbuffer_GetType
,
270 /* IDirect3DVertexBuffer9 */
271 d3d9_vertexbuffer_Lock
,
272 d3d9_vertexbuffer_Unlock
,
273 d3d9_vertexbuffer_GetDesc
,
276 static void STDMETHODCALLTYPE
d3d9_vertexbuffer_wined3d_object_destroyed(void *parent
)
278 HeapFree(GetProcessHeap(), 0, parent
);
281 static const struct wined3d_parent_ops d3d9_vertexbuffer_wined3d_parent_ops
=
283 d3d9_vertexbuffer_wined3d_object_destroyed
,
286 HRESULT
vertexbuffer_init(struct d3d9_vertexbuffer
*buffer
, struct d3d9_device
*device
,
287 UINT size
, UINT usage
, DWORD fvf
, D3DPOOL pool
)
291 buffer
->IDirect3DVertexBuffer9_iface
.lpVtbl
= &d3d9_vertexbuffer_vtbl
;
292 buffer
->refcount
= 1;
295 wined3d_mutex_lock();
296 hr
= wined3d_buffer_create_vb(device
->wined3d_device
, size
, usage
& WINED3DUSAGE_MASK
,
297 (enum wined3d_pool
)pool
, buffer
, &d3d9_vertexbuffer_wined3d_parent_ops
, &buffer
->wined3d_buffer
);
298 wined3d_mutex_unlock();
301 WARN("Failed to create wined3d buffer, hr %#x.\n", hr
);
305 buffer
->parent_device
= &device
->IDirect3DDevice9Ex_iface
;
306 IDirect3DDevice9Ex_AddRef(buffer
->parent_device
);
311 struct d3d9_vertexbuffer
*unsafe_impl_from_IDirect3DVertexBuffer9(IDirect3DVertexBuffer9
*iface
)
315 assert(iface
->lpVtbl
== &d3d9_vertexbuffer_vtbl
);
317 return impl_from_IDirect3DVertexBuffer9(iface
);
320 static inline struct d3d9_indexbuffer
*impl_from_IDirect3DIndexBuffer9(IDirect3DIndexBuffer9
*iface
)
322 return CONTAINING_RECORD(iface
, struct d3d9_indexbuffer
, IDirect3DIndexBuffer9_iface
);
325 static HRESULT WINAPI
d3d9_indexbuffer_QueryInterface(IDirect3DIndexBuffer9
*iface
, REFIID riid
, void **out
)
327 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
329 if (IsEqualGUID(riid
, &IID_IDirect3DIndexBuffer9
)
330 || IsEqualGUID(riid
, &IID_IDirect3DResource9
)
331 || IsEqualGUID(riid
, &IID_IUnknown
))
333 IDirect3DIndexBuffer9_AddRef(iface
);
338 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
341 return E_NOINTERFACE
;
344 static ULONG WINAPI
d3d9_indexbuffer_AddRef(IDirect3DIndexBuffer9
*iface
)
346 struct d3d9_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer9(iface
);
347 ULONG refcount
= InterlockedIncrement(&buffer
->refcount
);
349 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
353 IDirect3DDevice9Ex_AddRef(buffer
->parent_device
);
354 wined3d_mutex_lock();
355 wined3d_buffer_incref(buffer
->wined3d_buffer
);
356 wined3d_mutex_unlock();
362 static ULONG WINAPI
d3d9_indexbuffer_Release(IDirect3DIndexBuffer9
*iface
)
364 struct d3d9_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer9(iface
);
365 ULONG refcount
= InterlockedDecrement(&buffer
->refcount
);
367 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
371 IDirect3DDevice9Ex
*device
= buffer
->parent_device
;
373 wined3d_mutex_lock();
374 wined3d_buffer_decref(buffer
->wined3d_buffer
);
375 wined3d_mutex_unlock();
377 /* Release the device last, as it may cause the device to be destroyed. */
378 IDirect3DDevice9Ex_Release(device
);
384 static HRESULT WINAPI
d3d9_indexbuffer_GetDevice(IDirect3DIndexBuffer9
*iface
, IDirect3DDevice9
**device
)
386 struct d3d9_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer9(iface
);
388 TRACE("iface %p, device %p.\n", iface
, device
);
390 *device
= (IDirect3DDevice9
*)buffer
->parent_device
;
391 IDirect3DDevice9_AddRef(*device
);
393 TRACE("Returning device %p.\n", *device
);
398 static HRESULT WINAPI
d3d9_indexbuffer_SetPrivateData(IDirect3DIndexBuffer9
*iface
,
399 REFGUID guid
, const void *data
, DWORD data_size
, DWORD flags
)
401 struct d3d9_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer9(iface
);
402 struct wined3d_resource
*resource
;
405 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
406 iface
, debugstr_guid(guid
), data
, data_size
, flags
);
408 wined3d_mutex_lock();
409 resource
= wined3d_buffer_get_resource(buffer
->wined3d_buffer
);
410 hr
= wined3d_resource_set_private_data(resource
, guid
, data
, data_size
, flags
);
411 wined3d_mutex_unlock();
416 static HRESULT WINAPI
d3d9_indexbuffer_GetPrivateData(IDirect3DIndexBuffer9
*iface
,
417 REFGUID guid
, void *data
, DWORD
*data_size
)
419 struct d3d9_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer9(iface
);
420 struct wined3d_resource
*resource
;
423 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
424 iface
, debugstr_guid(guid
), data
, data_size
);
426 wined3d_mutex_lock();
427 resource
= wined3d_buffer_get_resource(buffer
->wined3d_buffer
);
428 hr
= wined3d_resource_get_private_data(resource
, guid
, data
, data_size
);
429 wined3d_mutex_unlock();
434 static HRESULT WINAPI
d3d9_indexbuffer_FreePrivateData(IDirect3DIndexBuffer9
*iface
, REFGUID guid
)
436 struct d3d9_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer9(iface
);
437 struct wined3d_resource
*resource
;
440 TRACE("iface %p, guid %s.\n", iface
, debugstr_guid(guid
));
442 wined3d_mutex_lock();
443 resource
= wined3d_buffer_get_resource(buffer
->wined3d_buffer
);
444 hr
= wined3d_resource_free_private_data(resource
, guid
);
445 wined3d_mutex_unlock();
450 static DWORD WINAPI
d3d9_indexbuffer_SetPriority(IDirect3DIndexBuffer9
*iface
, DWORD priority
)
452 struct d3d9_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer9(iface
);
455 TRACE("iface %p, priority %u.\n", iface
, priority
);
457 wined3d_mutex_lock();
458 previous
= wined3d_buffer_set_priority(buffer
->wined3d_buffer
, priority
);
459 wined3d_mutex_unlock();
464 static DWORD WINAPI
d3d9_indexbuffer_GetPriority(IDirect3DIndexBuffer9
*iface
)
466 struct d3d9_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer9(iface
);
469 TRACE("iface %p.\n", iface
);
471 wined3d_mutex_lock();
472 priority
= wined3d_buffer_get_priority(buffer
->wined3d_buffer
);
473 wined3d_mutex_unlock();
478 static void WINAPI
d3d9_indexbuffer_PreLoad(IDirect3DIndexBuffer9
*iface
)
480 struct d3d9_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer9(iface
);
482 TRACE("iface %p.\n", iface
);
484 wined3d_mutex_lock();
485 wined3d_buffer_preload(buffer
->wined3d_buffer
);
486 wined3d_mutex_unlock();
489 static D3DRESOURCETYPE WINAPI
d3d9_indexbuffer_GetType(IDirect3DIndexBuffer9
*iface
)
491 TRACE("iface %p.\n", iface
);
493 return D3DRTYPE_INDEXBUFFER
;
496 static HRESULT WINAPI
d3d9_indexbuffer_Lock(IDirect3DIndexBuffer9
*iface
,
497 UINT offset
, UINT size
, void **data
, DWORD flags
)
499 struct d3d9_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer9(iface
);
502 TRACE("iface %p, offset %u, size %u, data %p, flags %#x.\n",
503 iface
, offset
, size
, data
, flags
);
505 wined3d_mutex_lock();
506 hr
= wined3d_buffer_map(buffer
->wined3d_buffer
, offset
, size
, (BYTE
**)data
, flags
);
507 wined3d_mutex_unlock();
512 static HRESULT WINAPI
d3d9_indexbuffer_Unlock(IDirect3DIndexBuffer9
*iface
)
514 struct d3d9_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer9(iface
);
516 TRACE("iface %p.\n", iface
);
518 wined3d_mutex_lock();
519 wined3d_buffer_unmap(buffer
->wined3d_buffer
);
520 wined3d_mutex_unlock();
525 static HRESULT WINAPI
d3d9_indexbuffer_GetDesc(IDirect3DIndexBuffer9
*iface
, D3DINDEXBUFFER_DESC
*desc
)
527 struct d3d9_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer9(iface
);
528 struct wined3d_resource_desc wined3d_desc
;
529 struct wined3d_resource
*wined3d_resource
;
531 TRACE("iface %p, desc %p.\n", iface
, desc
);
533 wined3d_mutex_lock();
534 wined3d_resource
= wined3d_buffer_get_resource(buffer
->wined3d_buffer
);
535 wined3d_resource_get_desc(wined3d_resource
, &wined3d_desc
);
536 wined3d_mutex_unlock();
538 desc
->Format
= d3dformat_from_wined3dformat(buffer
->format
);
539 desc
->Usage
= wined3d_desc
.usage
& WINED3DUSAGE_MASK
;
540 desc
->Pool
= wined3d_desc
.pool
;
541 desc
->Size
= wined3d_desc
.size
;
542 desc
->Type
= D3DRTYPE_INDEXBUFFER
;
547 static const IDirect3DIndexBuffer9Vtbl d3d9_indexbuffer_vtbl
=
550 d3d9_indexbuffer_QueryInterface
,
551 d3d9_indexbuffer_AddRef
,
552 d3d9_indexbuffer_Release
,
553 /* IDirect3DResource9 */
554 d3d9_indexbuffer_GetDevice
,
555 d3d9_indexbuffer_SetPrivateData
,
556 d3d9_indexbuffer_GetPrivateData
,
557 d3d9_indexbuffer_FreePrivateData
,
558 d3d9_indexbuffer_SetPriority
,
559 d3d9_indexbuffer_GetPriority
,
560 d3d9_indexbuffer_PreLoad
,
561 d3d9_indexbuffer_GetType
,
562 /* IDirect3DIndexBuffer9 */
563 d3d9_indexbuffer_Lock
,
564 d3d9_indexbuffer_Unlock
,
565 d3d9_indexbuffer_GetDesc
,
568 static void STDMETHODCALLTYPE
d3d9_indexbuffer_wined3d_object_destroyed(void *parent
)
570 HeapFree(GetProcessHeap(), 0, parent
);
573 static const struct wined3d_parent_ops d3d9_indexbuffer_wined3d_parent_ops
=
575 d3d9_indexbuffer_wined3d_object_destroyed
,
578 HRESULT
indexbuffer_init(struct d3d9_indexbuffer
*buffer
, struct d3d9_device
*device
,
579 UINT size
, DWORD usage
, D3DFORMAT format
, D3DPOOL pool
)
583 buffer
->IDirect3DIndexBuffer9_iface
.lpVtbl
= &d3d9_indexbuffer_vtbl
;
584 buffer
->refcount
= 1;
585 buffer
->format
= wined3dformat_from_d3dformat(format
);
587 wined3d_mutex_lock();
588 hr
= wined3d_buffer_create_ib(device
->wined3d_device
, size
, usage
& WINED3DUSAGE_MASK
,
589 (enum wined3d_pool
)pool
, buffer
, &d3d9_indexbuffer_wined3d_parent_ops
, &buffer
->wined3d_buffer
);
590 wined3d_mutex_unlock();
593 WARN("Failed to create wined3d buffer, hr %#x.\n", hr
);
597 buffer
->parent_device
= &device
->IDirect3DDevice9Ex_iface
;
598 IDirect3DDevice9Ex_AddRef(buffer
->parent_device
);
603 struct d3d9_indexbuffer
*unsafe_impl_from_IDirect3DIndexBuffer9(IDirect3DIndexBuffer9
*iface
)
607 assert(iface
->lpVtbl
== &d3d9_indexbuffer_vtbl
);
609 return impl_from_IDirect3DIndexBuffer9(iface
);