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
20 #include "d3d8_private.h"
22 WINE_DEFAULT_DEBUG_CHANNEL(d3d8
);
24 static inline struct d3d8_vertexbuffer
*impl_from_IDirect3DVertexBuffer8(IDirect3DVertexBuffer8
*iface
)
26 return CONTAINING_RECORD(iface
, struct d3d8_vertexbuffer
, IDirect3DVertexBuffer8_iface
);
29 static HRESULT WINAPI
d3d8_vertexbuffer_QueryInterface(IDirect3DVertexBuffer8
*iface
, REFIID riid
, void **object
)
31 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
33 if (IsEqualGUID(riid
, &IID_IDirect3DVertexBuffer8
)
34 || IsEqualGUID(riid
, &IID_IDirect3DResource8
)
35 || IsEqualGUID(riid
, &IID_IUnknown
))
37 IDirect3DVertexBuffer8_AddRef(iface
);
42 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
48 static ULONG WINAPI
d3d8_vertexbuffer_AddRef(IDirect3DVertexBuffer8
*iface
)
50 struct d3d8_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer8(iface
);
51 ULONG refcount
= InterlockedIncrement(&buffer
->refcount
);
53 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
57 IDirect3DDevice8_AddRef(buffer
->parent_device
);
59 wined3d_buffer_incref(buffer
->wined3d_buffer
);
60 wined3d_mutex_unlock();
66 static ULONG WINAPI
d3d8_vertexbuffer_Release(IDirect3DVertexBuffer8
*iface
)
68 struct d3d8_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer8(iface
);
69 ULONG refcount
= InterlockedDecrement(&buffer
->refcount
);
71 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
75 IDirect3DDevice8
*device
= buffer
->parent_device
;
78 wined3d_buffer_decref(buffer
->wined3d_buffer
);
79 wined3d_mutex_unlock();
81 /* Release the device last, as it may cause the device to be destroyed. */
82 IDirect3DDevice8_Release(device
);
88 static HRESULT WINAPI
d3d8_vertexbuffer_GetDevice(IDirect3DVertexBuffer8
*iface
,
89 IDirect3DDevice8
**device
)
91 struct d3d8_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer8(iface
);
93 TRACE("iface %p, device %p.\n", iface
, device
);
95 *device
= buffer
->parent_device
;
96 IDirect3DDevice8_AddRef(*device
);
98 TRACE("Returning device %p.\n", *device
);
103 static HRESULT WINAPI
d3d8_vertexbuffer_SetPrivateData(IDirect3DVertexBuffer8
*iface
,
104 REFGUID guid
, const void *data
, DWORD data_size
, DWORD flags
)
106 struct d3d8_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer8(iface
);
107 struct wined3d_resource
*resource
;
110 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
111 iface
, debugstr_guid(guid
), data
, data_size
, flags
);
113 wined3d_mutex_lock();
114 resource
= wined3d_buffer_get_resource(buffer
->wined3d_buffer
);
115 hr
= wined3d_resource_set_private_data(resource
, guid
, data
, data_size
, flags
);
116 wined3d_mutex_unlock();
121 static HRESULT WINAPI
d3d8_vertexbuffer_GetPrivateData(IDirect3DVertexBuffer8
*iface
,
122 REFGUID guid
, void *data
, DWORD
*data_size
)
124 struct d3d8_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer8(iface
);
125 struct wined3d_resource
*resource
;
128 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
129 iface
, debugstr_guid(guid
), data
, data_size
);
131 wined3d_mutex_lock();
132 resource
= wined3d_buffer_get_resource(buffer
->wined3d_buffer
);
133 hr
= wined3d_resource_get_private_data(resource
, guid
, data
, data_size
);
134 wined3d_mutex_unlock();
139 static HRESULT WINAPI
d3d8_vertexbuffer_FreePrivateData(IDirect3DVertexBuffer8
*iface
, REFGUID guid
)
141 struct d3d8_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer8(iface
);
142 struct wined3d_resource
*resource
;
145 TRACE("iface %p, guid %s.\n", iface
, debugstr_guid(guid
));
147 wined3d_mutex_lock();
148 resource
= wined3d_buffer_get_resource(buffer
->wined3d_buffer
);
149 hr
= wined3d_resource_free_private_data(resource
, guid
);
150 wined3d_mutex_unlock();
155 static DWORD WINAPI
d3d8_vertexbuffer_SetPriority(IDirect3DVertexBuffer8
*iface
, DWORD priority
)
157 struct d3d8_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer8(iface
);
160 TRACE("iface %p, priority %u.\n", iface
, priority
);
162 wined3d_mutex_lock();
163 previous
= wined3d_buffer_set_priority(buffer
->wined3d_buffer
, priority
);
164 wined3d_mutex_unlock();
169 static DWORD WINAPI
d3d8_vertexbuffer_GetPriority(IDirect3DVertexBuffer8
*iface
)
171 struct d3d8_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer8(iface
);
174 TRACE("iface %p.\n", iface
);
176 wined3d_mutex_lock();
177 priority
= wined3d_buffer_get_priority(buffer
->wined3d_buffer
);
178 wined3d_mutex_unlock();
183 static void WINAPI
d3d8_vertexbuffer_PreLoad(IDirect3DVertexBuffer8
*iface
)
185 struct d3d8_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer8(iface
);
187 TRACE("iface %p.\n", iface
);
189 wined3d_mutex_lock();
190 wined3d_buffer_preload(buffer
->wined3d_buffer
);
191 wined3d_mutex_unlock();
194 static D3DRESOURCETYPE WINAPI
d3d8_vertexbuffer_GetType(IDirect3DVertexBuffer8
*iface
)
196 TRACE("iface %p.\n", iface
);
198 return D3DRTYPE_VERTEXBUFFER
;
201 static HRESULT WINAPI
d3d8_vertexbuffer_Lock(IDirect3DVertexBuffer8
*iface
, UINT offset
, UINT size
,
202 BYTE
**data
, DWORD flags
)
204 struct d3d8_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer8(iface
);
207 TRACE("iface %p, offset %u, size %u, data %p, flags %#x.\n",
208 iface
, offset
, size
, data
, flags
);
210 wined3d_mutex_lock();
211 hr
= wined3d_buffer_map(buffer
->wined3d_buffer
, offset
, size
, data
, flags
);
212 wined3d_mutex_unlock();
217 static HRESULT WINAPI
d3d8_vertexbuffer_Unlock(IDirect3DVertexBuffer8
*iface
)
219 struct d3d8_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer8(iface
);
221 TRACE("iface %p.\n", iface
);
223 wined3d_mutex_lock();
224 wined3d_buffer_unmap(buffer
->wined3d_buffer
);
225 wined3d_mutex_unlock();
230 static HRESULT WINAPI
d3d8_vertexbuffer_GetDesc(IDirect3DVertexBuffer8
*iface
,
231 D3DVERTEXBUFFER_DESC
*desc
)
233 struct d3d8_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer8(iface
);
234 struct wined3d_resource_desc wined3d_desc
;
235 struct wined3d_resource
*wined3d_resource
;
237 TRACE("iface %p, desc %p.\n", iface
, desc
);
239 wined3d_mutex_lock();
240 wined3d_resource
= wined3d_buffer_get_resource(buffer
->wined3d_buffer
);
241 wined3d_resource_get_desc(wined3d_resource
, &wined3d_desc
);
242 wined3d_mutex_unlock();
244 desc
->Type
= D3DRTYPE_VERTEXBUFFER
;
245 desc
->Usage
= wined3d_desc
.usage
& WINED3DUSAGE_MASK
;
246 desc
->Pool
= wined3d_desc
.pool
;
247 desc
->Size
= wined3d_desc
.size
;
248 desc
->FVF
= buffer
->fvf
;
249 desc
->Format
= D3DFMT_VERTEXDATA
;
254 static const IDirect3DVertexBuffer8Vtbl Direct3DVertexBuffer8_Vtbl
=
257 d3d8_vertexbuffer_QueryInterface
,
258 d3d8_vertexbuffer_AddRef
,
259 d3d8_vertexbuffer_Release
,
260 /* IDirect3DResource8 */
261 d3d8_vertexbuffer_GetDevice
,
262 d3d8_vertexbuffer_SetPrivateData
,
263 d3d8_vertexbuffer_GetPrivateData
,
264 d3d8_vertexbuffer_FreePrivateData
,
265 d3d8_vertexbuffer_SetPriority
,
266 d3d8_vertexbuffer_GetPriority
,
267 d3d8_vertexbuffer_PreLoad
,
268 d3d8_vertexbuffer_GetType
,
269 /* IDirect3DVertexBuffer8 */
270 d3d8_vertexbuffer_Lock
,
271 d3d8_vertexbuffer_Unlock
,
272 d3d8_vertexbuffer_GetDesc
,
275 static void STDMETHODCALLTYPE
d3d8_vertexbuffer_wined3d_object_destroyed(void *parent
)
277 HeapFree(GetProcessHeap(), 0, parent
);
280 static const struct wined3d_parent_ops d3d8_vertexbuffer_wined3d_parent_ops
=
282 d3d8_vertexbuffer_wined3d_object_destroyed
,
285 HRESULT
vertexbuffer_init(struct d3d8_vertexbuffer
*buffer
, struct d3d8_device
*device
,
286 UINT size
, DWORD usage
, DWORD fvf
, D3DPOOL pool
)
290 buffer
->IDirect3DVertexBuffer8_iface
.lpVtbl
= &Direct3DVertexBuffer8_Vtbl
;
291 buffer
->refcount
= 1;
294 wined3d_mutex_lock();
295 hr
= wined3d_buffer_create_vb(device
->wined3d_device
, size
, usage
& WINED3DUSAGE_MASK
,
296 (enum wined3d_pool
)pool
, buffer
, &d3d8_vertexbuffer_wined3d_parent_ops
, &buffer
->wined3d_buffer
);
297 wined3d_mutex_unlock();
300 WARN("Failed to create wined3d buffer, hr %#x.\n", hr
);
304 buffer
->parent_device
= &device
->IDirect3DDevice8_iface
;
305 IDirect3DDevice8_AddRef(buffer
->parent_device
);
310 struct d3d8_vertexbuffer
*unsafe_impl_from_IDirect3DVertexBuffer8(IDirect3DVertexBuffer8
*iface
)
314 assert(iface
->lpVtbl
== &Direct3DVertexBuffer8_Vtbl
);
316 return impl_from_IDirect3DVertexBuffer8(iface
);
319 static inline struct d3d8_indexbuffer
*impl_from_IDirect3DIndexBuffer8(IDirect3DIndexBuffer8
*iface
)
321 return CONTAINING_RECORD(iface
, struct d3d8_indexbuffer
, IDirect3DIndexBuffer8_iface
);
324 static HRESULT WINAPI
d3d8_indexbuffer_QueryInterface(IDirect3DIndexBuffer8
*iface
, REFIID riid
, void **object
)
326 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
328 if (IsEqualGUID(riid
, &IID_IDirect3DIndexBuffer8
)
329 || IsEqualGUID(riid
, &IID_IDirect3DResource8
)
330 || IsEqualGUID(riid
, &IID_IUnknown
))
332 IDirect3DIndexBuffer8_AddRef(iface
);
337 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
340 return E_NOINTERFACE
;
343 static ULONG WINAPI
d3d8_indexbuffer_AddRef(IDirect3DIndexBuffer8
*iface
)
345 struct d3d8_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer8(iface
);
346 ULONG refcount
= InterlockedIncrement(&buffer
->refcount
);
348 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
352 IDirect3DDevice8_AddRef(buffer
->parent_device
);
353 wined3d_mutex_lock();
354 wined3d_buffer_incref(buffer
->wined3d_buffer
);
355 wined3d_mutex_unlock();
361 static ULONG WINAPI
d3d8_indexbuffer_Release(IDirect3DIndexBuffer8
*iface
)
363 struct d3d8_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer8(iface
);
364 ULONG refcount
= InterlockedDecrement(&buffer
->refcount
);
366 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
370 IDirect3DDevice8
*device
= buffer
->parent_device
;
372 wined3d_mutex_lock();
373 wined3d_buffer_decref(buffer
->wined3d_buffer
);
374 wined3d_mutex_unlock();
376 /* Release the device last, as it may cause the device to be destroyed. */
377 IDirect3DDevice8_Release(device
);
383 static HRESULT WINAPI
d3d8_indexbuffer_GetDevice(IDirect3DIndexBuffer8
*iface
,
384 IDirect3DDevice8
**device
)
386 struct d3d8_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer8(iface
);
388 TRACE("iface %p, device %p.\n", iface
, device
);
390 *device
= buffer
->parent_device
;
391 IDirect3DDevice8_AddRef(*device
);
393 TRACE("Returning device %p.\n", *device
);
398 static HRESULT WINAPI
d3d8_indexbuffer_SetPrivateData(IDirect3DIndexBuffer8
*iface
,
399 REFGUID guid
, const void *data
, DWORD data_size
, DWORD flags
)
401 struct d3d8_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer8(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
d3d8_indexbuffer_GetPrivateData(IDirect3DIndexBuffer8
*iface
,
417 REFGUID guid
, void *data
, DWORD
*data_size
)
419 struct d3d8_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer8(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
d3d8_indexbuffer_FreePrivateData(IDirect3DIndexBuffer8
*iface
, REFGUID guid
)
436 struct d3d8_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer8(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
d3d8_indexbuffer_SetPriority(IDirect3DIndexBuffer8
*iface
, DWORD priority
)
452 struct d3d8_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer8(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
d3d8_indexbuffer_GetPriority(IDirect3DIndexBuffer8
*iface
)
466 struct d3d8_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer8(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
d3d8_indexbuffer_PreLoad(IDirect3DIndexBuffer8
*iface
)
480 struct d3d8_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer8(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
d3d8_indexbuffer_GetType(IDirect3DIndexBuffer8
*iface
)
491 TRACE("iface %p.\n", iface
);
493 return D3DRTYPE_INDEXBUFFER
;
496 static HRESULT WINAPI
d3d8_indexbuffer_Lock(IDirect3DIndexBuffer8
*iface
, UINT offset
, UINT size
,
497 BYTE
**data
, DWORD flags
)
499 struct d3d8_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer8(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
, data
, flags
);
507 wined3d_mutex_unlock();
512 static HRESULT WINAPI
d3d8_indexbuffer_Unlock(IDirect3DIndexBuffer8
*iface
)
514 struct d3d8_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer8(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
d3d8_indexbuffer_GetDesc(IDirect3DIndexBuffer8
*iface
,
526 D3DINDEXBUFFER_DESC
*desc
)
528 struct d3d8_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer8(iface
);
529 struct wined3d_resource_desc wined3d_desc
;
530 struct wined3d_resource
*wined3d_resource
;
532 TRACE("iface %p, desc %p.\n", iface
, desc
);
534 wined3d_mutex_lock();
535 wined3d_resource
= wined3d_buffer_get_resource(buffer
->wined3d_buffer
);
536 wined3d_resource_get_desc(wined3d_resource
, &wined3d_desc
);
537 wined3d_mutex_unlock();
539 desc
->Format
= d3dformat_from_wined3dformat(buffer
->format
);
540 desc
->Type
= D3DRTYPE_INDEXBUFFER
;
541 desc
->Usage
= wined3d_desc
.usage
& WINED3DUSAGE_MASK
;
542 desc
->Pool
= wined3d_desc
.pool
;
543 desc
->Size
= wined3d_desc
.size
;
548 static const IDirect3DIndexBuffer8Vtbl d3d8_indexbuffer_vtbl
=
551 d3d8_indexbuffer_QueryInterface
,
552 d3d8_indexbuffer_AddRef
,
553 d3d8_indexbuffer_Release
,
554 /* IDirect3DResource8 */
555 d3d8_indexbuffer_GetDevice
,
556 d3d8_indexbuffer_SetPrivateData
,
557 d3d8_indexbuffer_GetPrivateData
,
558 d3d8_indexbuffer_FreePrivateData
,
559 d3d8_indexbuffer_SetPriority
,
560 d3d8_indexbuffer_GetPriority
,
561 d3d8_indexbuffer_PreLoad
,
562 d3d8_indexbuffer_GetType
,
563 /* IDirect3DIndexBuffer8 */
564 d3d8_indexbuffer_Lock
,
565 d3d8_indexbuffer_Unlock
,
566 d3d8_indexbuffer_GetDesc
,
569 static void STDMETHODCALLTYPE
d3d8_indexbuffer_wined3d_object_destroyed(void *parent
)
571 HeapFree(GetProcessHeap(), 0, parent
);
574 static const struct wined3d_parent_ops d3d8_indexbuffer_wined3d_parent_ops
=
576 d3d8_indexbuffer_wined3d_object_destroyed
,
579 HRESULT
indexbuffer_init(struct d3d8_indexbuffer
*buffer
, struct d3d8_device
*device
,
580 UINT size
, DWORD usage
, D3DFORMAT format
, D3DPOOL pool
)
584 buffer
->IDirect3DIndexBuffer8_iface
.lpVtbl
= &d3d8_indexbuffer_vtbl
;
585 buffer
->refcount
= 1;
586 buffer
->format
= wined3dformat_from_d3dformat(format
);
588 wined3d_mutex_lock();
589 hr
= wined3d_buffer_create_ib(device
->wined3d_device
, size
, usage
& WINED3DUSAGE_MASK
,
590 (enum wined3d_pool
)pool
, buffer
, &d3d8_indexbuffer_wined3d_parent_ops
, &buffer
->wined3d_buffer
);
591 wined3d_mutex_unlock();
594 WARN("Failed to create wined3d buffer, hr %#x.\n", hr
);
598 buffer
->parent_device
= &device
->IDirect3DDevice8_iface
;
599 IDirect3DDevice8_AddRef(buffer
->parent_device
);
604 struct d3d8_indexbuffer
*unsafe_impl_from_IDirect3DIndexBuffer8(IDirect3DIndexBuffer8
*iface
)
608 assert(iface
->lpVtbl
== &d3d8_indexbuffer_vtbl
);
610 return impl_from_IDirect3DIndexBuffer8(iface
);