msvcrt: memmove_s shouldn't zero its output buffer on error.
[wine/multimedia.git] / dlls / d3d8 / buffer.c
blobb0a11ad633173f98d45ca17cf54e1bb98dda64c5
1 /*
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
19 #include "config.h"
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 IUnknown_AddRef(iface);
38 *object = iface;
39 return S_OK;
42 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
44 *object = NULL;
45 return E_NOINTERFACE;
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);
55 if (refcount == 1)
57 IDirect3DDevice8_AddRef(buffer->parent_device);
58 wined3d_mutex_lock();
59 wined3d_buffer_incref(buffer->wined3d_buffer);
60 wined3d_mutex_unlock();
63 return refcount;
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);
73 if (!refcount)
75 IDirect3DDevice8 *device = buffer->parent_device;
77 wined3d_mutex_lock();
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);
85 return refcount;
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);
100 return D3D_OK;
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;
108 HRESULT hr;
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();
118 return hr;
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;
126 HRESULT hr;
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();
136 return hr;
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;
143 HRESULT hr;
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();
152 return hr;
155 static DWORD WINAPI d3d8_vertexbuffer_SetPriority(IDirect3DVertexBuffer8 *iface, DWORD priority)
157 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
158 DWORD previous;
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();
166 return previous;
169 static DWORD WINAPI d3d8_vertexbuffer_GetPriority(IDirect3DVertexBuffer8 *iface)
171 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
172 DWORD priority;
174 TRACE("iface %p.\n", iface);
176 wined3d_mutex_lock();
177 priority = wined3d_buffer_get_priority(buffer->wined3d_buffer);
178 wined3d_mutex_unlock();
180 return priority;
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);
205 HRESULT hr;
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();
214 return hr;
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();
227 return D3D_OK;
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;
251 return D3D_OK;
254 static const IDirect3DVertexBuffer8Vtbl Direct3DVertexBuffer8_Vtbl =
256 /* IUnknown */
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)
288 HRESULT hr;
290 buffer->IDirect3DVertexBuffer8_iface.lpVtbl = &Direct3DVertexBuffer8_Vtbl;
291 buffer->refcount = 1;
292 buffer->fvf = fvf;
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();
298 if (FAILED(hr))
300 WARN("Failed to create wined3d buffer, hr %#x.\n", hr);
301 return hr;
304 buffer->parent_device = &device->IDirect3DDevice8_iface;
305 IUnknown_AddRef(buffer->parent_device);
307 return D3D_OK;
310 struct d3d8_vertexbuffer *unsafe_impl_from_IDirect3DVertexBuffer8(IDirect3DVertexBuffer8 *iface)
312 if (!iface)
313 return NULL;
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 IUnknown_AddRef(iface);
333 *object = iface;
334 return S_OK;
337 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
339 *object = NULL;
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);
350 if (refcount == 1)
352 IDirect3DDevice8_AddRef(buffer->parent_device);
353 wined3d_mutex_lock();
354 wined3d_buffer_incref(buffer->wined3d_buffer);
355 wined3d_mutex_unlock();
358 return refcount;
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);
368 if (!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);
380 return refcount;
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);
395 return D3D_OK;
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;
403 HRESULT hr;
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();
413 return hr;
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;
421 HRESULT hr;
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();
431 return hr;
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;
438 HRESULT hr;
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();
447 return hr;
450 static DWORD WINAPI d3d8_indexbuffer_SetPriority(IDirect3DIndexBuffer8 *iface, DWORD priority)
452 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
453 DWORD previous;
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();
461 return previous;
464 static DWORD WINAPI d3d8_indexbuffer_GetPriority(IDirect3DIndexBuffer8 *iface)
466 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
467 DWORD priority;
469 TRACE("iface %p.\n", iface);
471 wined3d_mutex_lock();
472 priority = wined3d_buffer_get_priority(buffer->wined3d_buffer);
473 wined3d_mutex_unlock();
475 return priority;
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);
500 HRESULT hr;
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();
509 return hr;
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();
522 return D3D_OK;
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;
545 return D3D_OK;
548 static const IDirect3DIndexBuffer8Vtbl d3d8_indexbuffer_vtbl =
550 /* IUnknown */
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)
582 HRESULT hr;
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();
592 if (FAILED(hr))
594 WARN("Failed to create wined3d buffer, hr %#x.\n", hr);
595 return hr;
598 buffer->parent_device = &device->IDirect3DDevice8_iface;
599 IUnknown_AddRef(buffer->parent_device);
601 return D3D_OK;
604 struct d3d8_indexbuffer *unsafe_impl_from_IDirect3DIndexBuffer8(IDirect3DIndexBuffer8 *iface)
606 if (!iface)
607 return NULL;
608 assert(iface->lpVtbl == &d3d8_indexbuffer_vtbl);
610 return impl_from_IDirect3DIndexBuffer8(iface);