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);