2 * Copyright 2005 Oliver Stieber
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "d3d8_private.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(d3d8
);
25 static inline IDirect3DVertexBuffer8Impl
*impl_from_IDirect3DVertexBuffer8(IDirect3DVertexBuffer8
*iface
)
27 return CONTAINING_RECORD(iface
, IDirect3DVertexBuffer8Impl
, IDirect3DVertexBuffer8_iface
);
30 static HRESULT WINAPI
d3d8_vertexbuffer_QueryInterface(IDirect3DVertexBuffer8
*iface
, REFIID riid
, void **object
)
32 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
34 if (IsEqualGUID(riid
, &IID_IDirect3DVertexBuffer8
)
35 || IsEqualGUID(riid
, &IID_IDirect3DResource8
)
36 || IsEqualGUID(riid
, &IID_IUnknown
))
38 IUnknown_AddRef(iface
);
43 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
49 static ULONG WINAPI
d3d8_vertexbuffer_AddRef(IDirect3DVertexBuffer8
*iface
)
51 IDirect3DVertexBuffer8Impl
*buffer
= impl_from_IDirect3DVertexBuffer8(iface
);
52 ULONG refcount
= InterlockedIncrement(&buffer
->ref
);
54 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
58 IDirect3DDevice8_AddRef(buffer
->parentDevice
);
60 wined3d_buffer_incref(buffer
->wineD3DVertexBuffer
);
61 wined3d_mutex_unlock();
67 static ULONG WINAPI
d3d8_vertexbuffer_Release(IDirect3DVertexBuffer8
*iface
)
69 IDirect3DVertexBuffer8Impl
*buffer
= impl_from_IDirect3DVertexBuffer8(iface
);
70 ULONG refcount
= InterlockedDecrement(&buffer
->ref
);
72 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
76 IDirect3DDevice8
*device
= buffer
->parentDevice
;
79 wined3d_buffer_decref(buffer
->wineD3DVertexBuffer
);
80 wined3d_mutex_unlock();
82 /* Release the device last, as it may cause the device to be destroyed. */
83 IDirect3DDevice8_Release(device
);
89 static HRESULT WINAPI
d3d8_vertexbuffer_GetDevice(IDirect3DVertexBuffer8
*iface
,
90 IDirect3DDevice8
**device
)
92 IDirect3DVertexBuffer8Impl
*buffer
= impl_from_IDirect3DVertexBuffer8(iface
);
94 TRACE("iface %p, device %p.\n", iface
, device
);
96 *device
= buffer
->parentDevice
;
97 IDirect3DDevice8_AddRef(*device
);
99 TRACE("Returning device %p.\n", *device
);
104 static HRESULT WINAPI
d3d8_vertexbuffer_SetPrivateData(IDirect3DVertexBuffer8
*iface
,
105 REFGUID guid
, const void *data
, DWORD data_size
, DWORD flags
)
107 IDirect3DVertexBuffer8Impl
*buffer
= impl_from_IDirect3DVertexBuffer8(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
->wineD3DVertexBuffer
);
116 hr
= wined3d_resource_set_private_data(resource
, guid
, data
, data_size
, flags
);
117 wined3d_mutex_unlock();
122 static HRESULT WINAPI
d3d8_vertexbuffer_GetPrivateData(IDirect3DVertexBuffer8
*iface
,
123 REFGUID guid
, void *data
, DWORD
*data_size
)
125 IDirect3DVertexBuffer8Impl
*buffer
= impl_from_IDirect3DVertexBuffer8(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
->wineD3DVertexBuffer
);
134 hr
= wined3d_resource_get_private_data(resource
, guid
, data
, data_size
);
135 wined3d_mutex_unlock();
140 static HRESULT WINAPI
d3d8_vertexbuffer_FreePrivateData(IDirect3DVertexBuffer8
*iface
, REFGUID guid
)
142 IDirect3DVertexBuffer8Impl
*buffer
= impl_from_IDirect3DVertexBuffer8(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
->wineD3DVertexBuffer
);
150 hr
= wined3d_resource_free_private_data(resource
, guid
);
151 wined3d_mutex_unlock();
156 static DWORD WINAPI
d3d8_vertexbuffer_SetPriority(IDirect3DVertexBuffer8
*iface
, DWORD priority
)
158 IDirect3DVertexBuffer8Impl
*buffer
= impl_from_IDirect3DVertexBuffer8(iface
);
161 TRACE("iface %p, priority %u.\n", iface
, priority
);
163 wined3d_mutex_lock();
164 previous
= wined3d_buffer_set_priority(buffer
->wineD3DVertexBuffer
, priority
);
165 wined3d_mutex_unlock();
170 static DWORD WINAPI
d3d8_vertexbuffer_GetPriority(IDirect3DVertexBuffer8
*iface
)
172 IDirect3DVertexBuffer8Impl
*buffer
= impl_from_IDirect3DVertexBuffer8(iface
);
175 TRACE("iface %p.\n", iface
);
177 wined3d_mutex_lock();
178 priority
= wined3d_buffer_get_priority(buffer
->wineD3DVertexBuffer
);
179 wined3d_mutex_unlock();
184 static void WINAPI
d3d8_vertexbuffer_PreLoad(IDirect3DVertexBuffer8
*iface
)
186 IDirect3DVertexBuffer8Impl
*buffer
= impl_from_IDirect3DVertexBuffer8(iface
);
188 TRACE("iface %p.\n", iface
);
190 wined3d_mutex_lock();
191 wined3d_buffer_preload(buffer
->wineD3DVertexBuffer
);
192 wined3d_mutex_unlock();
195 static D3DRESOURCETYPE WINAPI
d3d8_vertexbuffer_GetType(IDirect3DVertexBuffer8
*iface
)
197 TRACE("iface %p.\n", iface
);
199 return D3DRTYPE_VERTEXBUFFER
;
202 static HRESULT WINAPI
d3d8_vertexbuffer_Lock(IDirect3DVertexBuffer8
*iface
, UINT offset
, UINT size
,
203 BYTE
**data
, DWORD flags
)
205 IDirect3DVertexBuffer8Impl
*buffer
= impl_from_IDirect3DVertexBuffer8(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
->wineD3DVertexBuffer
, offset
, size
, data
, flags
);
213 wined3d_mutex_unlock();
218 static HRESULT WINAPI
d3d8_vertexbuffer_Unlock(IDirect3DVertexBuffer8
*iface
)
220 IDirect3DVertexBuffer8Impl
*buffer
= impl_from_IDirect3DVertexBuffer8(iface
);
222 TRACE("iface %p.\n", iface
);
224 wined3d_mutex_lock();
225 wined3d_buffer_unmap(buffer
->wineD3DVertexBuffer
);
226 wined3d_mutex_unlock();
231 static HRESULT WINAPI
d3d8_vertexbuffer_GetDesc(IDirect3DVertexBuffer8
*iface
,
232 D3DVERTEXBUFFER_DESC
*desc
)
234 IDirect3DVertexBuffer8Impl
*buffer
= impl_from_IDirect3DVertexBuffer8(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
->wineD3DVertexBuffer
);
242 wined3d_resource_get_desc(wined3d_resource
, &wined3d_desc
);
243 wined3d_mutex_unlock();
245 desc
->Type
= D3DRTYPE_VERTEXBUFFER
;
246 desc
->Usage
= wined3d_desc
.usage
& WINED3DUSAGE_MASK
;
247 desc
->Pool
= wined3d_desc
.pool
;
248 desc
->Size
= wined3d_desc
.size
;
249 desc
->FVF
= buffer
->fvf
;
250 desc
->Format
= D3DFMT_VERTEXDATA
;
255 static const IDirect3DVertexBuffer8Vtbl Direct3DVertexBuffer8_Vtbl
=
258 d3d8_vertexbuffer_QueryInterface
,
259 d3d8_vertexbuffer_AddRef
,
260 d3d8_vertexbuffer_Release
,
261 /* IDirect3DResource8 */
262 d3d8_vertexbuffer_GetDevice
,
263 d3d8_vertexbuffer_SetPrivateData
,
264 d3d8_vertexbuffer_GetPrivateData
,
265 d3d8_vertexbuffer_FreePrivateData
,
266 d3d8_vertexbuffer_SetPriority
,
267 d3d8_vertexbuffer_GetPriority
,
268 d3d8_vertexbuffer_PreLoad
,
269 d3d8_vertexbuffer_GetType
,
270 /* IDirect3DVertexBuffer8 */
271 d3d8_vertexbuffer_Lock
,
272 d3d8_vertexbuffer_Unlock
,
273 d3d8_vertexbuffer_GetDesc
,
276 static void STDMETHODCALLTYPE
d3d8_vertexbuffer_wined3d_object_destroyed(void *parent
)
278 HeapFree(GetProcessHeap(), 0, parent
);
281 static const struct wined3d_parent_ops d3d8_vertexbuffer_wined3d_parent_ops
=
283 d3d8_vertexbuffer_wined3d_object_destroyed
,
286 HRESULT
vertexbuffer_init(IDirect3DVertexBuffer8Impl
*buffer
, IDirect3DDevice8Impl
*device
,
287 UINT size
, DWORD usage
, DWORD fvf
, D3DPOOL pool
)
291 buffer
->IDirect3DVertexBuffer8_iface
.lpVtbl
= &Direct3DVertexBuffer8_Vtbl
;
295 wined3d_mutex_lock();
296 hr
= wined3d_buffer_create_vb(device
->wined3d_device
, size
, usage
& WINED3DUSAGE_MASK
,
297 (enum wined3d_pool
)pool
, buffer
, &d3d8_vertexbuffer_wined3d_parent_ops
, &buffer
->wineD3DVertexBuffer
);
298 wined3d_mutex_unlock();
301 WARN("Failed to create wined3d buffer, hr %#x.\n", hr
);
305 buffer
->parentDevice
= &device
->IDirect3DDevice8_iface
;
306 IUnknown_AddRef(buffer
->parentDevice
);
311 IDirect3DVertexBuffer8Impl
*unsafe_impl_from_IDirect3DVertexBuffer8(IDirect3DVertexBuffer8
*iface
)
315 assert(iface
->lpVtbl
== &Direct3DVertexBuffer8_Vtbl
);
317 return impl_from_IDirect3DVertexBuffer8(iface
);
320 static inline IDirect3DIndexBuffer8Impl
*impl_from_IDirect3DIndexBuffer8(IDirect3DIndexBuffer8
*iface
)
322 return CONTAINING_RECORD(iface
, IDirect3DIndexBuffer8Impl
, IDirect3DIndexBuffer8_iface
);
325 static HRESULT WINAPI
d3d8_indexbuffer_QueryInterface(IDirect3DIndexBuffer8
*iface
, REFIID riid
, void **object
)
327 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
329 if (IsEqualGUID(riid
, &IID_IDirect3DIndexBuffer8
)
330 || IsEqualGUID(riid
, &IID_IDirect3DResource8
)
331 || IsEqualGUID(riid
, &IID_IUnknown
))
333 IUnknown_AddRef(iface
);
338 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
341 return E_NOINTERFACE
;
344 static ULONG WINAPI
d3d8_indexbuffer_AddRef(IDirect3DIndexBuffer8
*iface
)
346 IDirect3DIndexBuffer8Impl
*buffer
= impl_from_IDirect3DIndexBuffer8(iface
);
347 ULONG refcount
= InterlockedIncrement(&buffer
->ref
);
349 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
353 IDirect3DDevice8_AddRef(buffer
->parentDevice
);
354 wined3d_mutex_lock();
355 wined3d_buffer_incref(buffer
->wineD3DIndexBuffer
);
356 wined3d_mutex_unlock();
362 static ULONG WINAPI
d3d8_indexbuffer_Release(IDirect3DIndexBuffer8
*iface
)
364 IDirect3DIndexBuffer8Impl
*buffer
= impl_from_IDirect3DIndexBuffer8(iface
);
365 ULONG refcount
= InterlockedDecrement(&buffer
->ref
);
367 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
371 IDirect3DDevice8
*device
= buffer
->parentDevice
;
373 wined3d_mutex_lock();
374 wined3d_buffer_decref(buffer
->wineD3DIndexBuffer
);
375 wined3d_mutex_unlock();
377 /* Release the device last, as it may cause the device to be destroyed. */
378 IDirect3DDevice8_Release(device
);
384 static HRESULT WINAPI
d3d8_indexbuffer_GetDevice(IDirect3DIndexBuffer8
*iface
,
385 IDirect3DDevice8
**device
)
387 IDirect3DIndexBuffer8Impl
*buffer
= impl_from_IDirect3DIndexBuffer8(iface
);
389 TRACE("iface %p, device %p.\n", iface
, device
);
391 *device
= buffer
->parentDevice
;
392 IDirect3DDevice8_AddRef(*device
);
394 TRACE("Returning device %p.\n", *device
);
399 static HRESULT WINAPI
d3d8_indexbuffer_SetPrivateData(IDirect3DIndexBuffer8
*iface
,
400 REFGUID guid
, const void *data
, DWORD data_size
, DWORD flags
)
402 IDirect3DIndexBuffer8Impl
*buffer
= impl_from_IDirect3DIndexBuffer8(iface
);
403 struct wined3d_resource
*resource
;
406 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
407 iface
, debugstr_guid(guid
), data
, data_size
, flags
);
409 wined3d_mutex_lock();
410 resource
= wined3d_buffer_get_resource(buffer
->wineD3DIndexBuffer
);
411 hr
= wined3d_resource_set_private_data(resource
, guid
, data
, data_size
, flags
);
412 wined3d_mutex_unlock();
417 static HRESULT WINAPI
d3d8_indexbuffer_GetPrivateData(IDirect3DIndexBuffer8
*iface
,
418 REFGUID guid
, void *data
, DWORD
*data_size
)
420 IDirect3DIndexBuffer8Impl
*buffer
= impl_from_IDirect3DIndexBuffer8(iface
);
421 struct wined3d_resource
*resource
;
424 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
425 iface
, debugstr_guid(guid
), data
, data_size
);
427 wined3d_mutex_lock();
428 resource
= wined3d_buffer_get_resource(buffer
->wineD3DIndexBuffer
);
429 hr
= wined3d_resource_get_private_data(resource
, guid
, data
, data_size
);
430 wined3d_mutex_unlock();
435 static HRESULT WINAPI
d3d8_indexbuffer_FreePrivateData(IDirect3DIndexBuffer8
*iface
, REFGUID guid
)
437 IDirect3DIndexBuffer8Impl
*buffer
= impl_from_IDirect3DIndexBuffer8(iface
);
438 struct wined3d_resource
*resource
;
441 TRACE("iface %p, guid %s.\n", iface
, debugstr_guid(guid
));
443 wined3d_mutex_lock();
444 resource
= wined3d_buffer_get_resource(buffer
->wineD3DIndexBuffer
);
445 hr
= wined3d_resource_free_private_data(resource
, guid
);
446 wined3d_mutex_unlock();
451 static DWORD WINAPI
d3d8_indexbuffer_SetPriority(IDirect3DIndexBuffer8
*iface
, DWORD priority
)
453 IDirect3DIndexBuffer8Impl
*buffer
= impl_from_IDirect3DIndexBuffer8(iface
);
456 TRACE("iface %p, priority %u.\n", iface
, priority
);
458 wined3d_mutex_lock();
459 previous
= wined3d_buffer_set_priority(buffer
->wineD3DIndexBuffer
, priority
);
460 wined3d_mutex_unlock();
465 static DWORD WINAPI
d3d8_indexbuffer_GetPriority(IDirect3DIndexBuffer8
*iface
)
467 IDirect3DIndexBuffer8Impl
*buffer
= impl_from_IDirect3DIndexBuffer8(iface
);
470 TRACE("iface %p.\n", iface
);
472 wined3d_mutex_lock();
473 priority
= wined3d_buffer_get_priority(buffer
->wineD3DIndexBuffer
);
474 wined3d_mutex_unlock();
479 static void WINAPI
d3d8_indexbuffer_PreLoad(IDirect3DIndexBuffer8
*iface
)
481 IDirect3DIndexBuffer8Impl
*buffer
= impl_from_IDirect3DIndexBuffer8(iface
);
483 TRACE("iface %p.\n", iface
);
485 wined3d_mutex_lock();
486 wined3d_buffer_preload(buffer
->wineD3DIndexBuffer
);
487 wined3d_mutex_unlock();
490 static D3DRESOURCETYPE WINAPI
d3d8_indexbuffer_GetType(IDirect3DIndexBuffer8
*iface
)
492 TRACE("iface %p.\n", iface
);
494 return D3DRTYPE_INDEXBUFFER
;
497 static HRESULT WINAPI
d3d8_indexbuffer_Lock(IDirect3DIndexBuffer8
*iface
, UINT offset
, UINT size
,
498 BYTE
**data
, DWORD flags
)
500 IDirect3DIndexBuffer8Impl
*buffer
= impl_from_IDirect3DIndexBuffer8(iface
);
503 TRACE("iface %p, offset %u, size %u, data %p, flags %#x.\n",
504 iface
, offset
, size
, data
, flags
);
506 wined3d_mutex_lock();
507 hr
= wined3d_buffer_map(buffer
->wineD3DIndexBuffer
, offset
, size
, data
, flags
);
508 wined3d_mutex_unlock();
513 static HRESULT WINAPI
d3d8_indexbuffer_Unlock(IDirect3DIndexBuffer8
*iface
)
515 IDirect3DIndexBuffer8Impl
*buffer
= impl_from_IDirect3DIndexBuffer8(iface
);
517 TRACE("iface %p.\n", iface
);
519 wined3d_mutex_lock();
520 wined3d_buffer_unmap(buffer
->wineD3DIndexBuffer
);
521 wined3d_mutex_unlock();
526 static HRESULT WINAPI
d3d8_indexbuffer_GetDesc(IDirect3DIndexBuffer8
*iface
,
527 D3DINDEXBUFFER_DESC
*desc
)
529 IDirect3DIndexBuffer8Impl
*buffer
= impl_from_IDirect3DIndexBuffer8(iface
);
530 struct wined3d_resource_desc wined3d_desc
;
531 struct wined3d_resource
*wined3d_resource
;
533 TRACE("iface %p, desc %p.\n", iface
, desc
);
535 wined3d_mutex_lock();
536 wined3d_resource
= wined3d_buffer_get_resource(buffer
->wineD3DIndexBuffer
);
537 wined3d_resource_get_desc(wined3d_resource
, &wined3d_desc
);
538 wined3d_mutex_unlock();
540 desc
->Format
= d3dformat_from_wined3dformat(buffer
->format
);
541 desc
->Type
= D3DRTYPE_INDEXBUFFER
;
542 desc
->Usage
= wined3d_desc
.usage
& WINED3DUSAGE_MASK
;
543 desc
->Pool
= wined3d_desc
.pool
;
544 desc
->Size
= wined3d_desc
.size
;
549 static const IDirect3DIndexBuffer8Vtbl d3d8_indexbuffer_vtbl
=
552 d3d8_indexbuffer_QueryInterface
,
553 d3d8_indexbuffer_AddRef
,
554 d3d8_indexbuffer_Release
,
555 /* IDirect3DResource8 */
556 d3d8_indexbuffer_GetDevice
,
557 d3d8_indexbuffer_SetPrivateData
,
558 d3d8_indexbuffer_GetPrivateData
,
559 d3d8_indexbuffer_FreePrivateData
,
560 d3d8_indexbuffer_SetPriority
,
561 d3d8_indexbuffer_GetPriority
,
562 d3d8_indexbuffer_PreLoad
,
563 d3d8_indexbuffer_GetType
,
564 /* IDirect3DIndexBuffer8 */
565 d3d8_indexbuffer_Lock
,
566 d3d8_indexbuffer_Unlock
,
567 d3d8_indexbuffer_GetDesc
,
570 static void STDMETHODCALLTYPE
d3d8_indexbuffer_wined3d_object_destroyed(void *parent
)
572 HeapFree(GetProcessHeap(), 0, parent
);
575 static const struct wined3d_parent_ops d3d8_indexbuffer_wined3d_parent_ops
=
577 d3d8_indexbuffer_wined3d_object_destroyed
,
580 HRESULT
indexbuffer_init(IDirect3DIndexBuffer8Impl
*buffer
, IDirect3DDevice8Impl
*device
,
581 UINT size
, DWORD usage
, D3DFORMAT format
, D3DPOOL pool
)
585 buffer
->IDirect3DIndexBuffer8_iface
.lpVtbl
= &d3d8_indexbuffer_vtbl
;
587 buffer
->format
= wined3dformat_from_d3dformat(format
);
589 wined3d_mutex_lock();
590 hr
= wined3d_buffer_create_ib(device
->wined3d_device
, size
, usage
& WINED3DUSAGE_MASK
,
591 (enum wined3d_pool
)pool
, buffer
, &d3d8_indexbuffer_wined3d_parent_ops
, &buffer
->wineD3DIndexBuffer
);
592 wined3d_mutex_unlock();
595 WARN("Failed to create wined3d buffer, hr %#x.\n", hr
);
599 buffer
->parentDevice
= &device
->IDirect3DDevice8_iface
;
600 IUnknown_AddRef(buffer
->parentDevice
);
605 IDirect3DIndexBuffer8Impl
*unsafe_impl_from_IDirect3DIndexBuffer8(IDirect3DIndexBuffer8
*iface
)
609 assert(iface
->lpVtbl
== &d3d8_indexbuffer_vtbl
);
611 return impl_from_IDirect3DIndexBuffer8(iface
);