- Sync with trunk r58248 to bring the latest changes from Amine (headers) and others...
[reactos.git] / dll / directx / wine / d3d8 / buffer.c
1 /*
2 * Copyright 2005 Oliver Stieber
3 *
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.
8 *
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.
13 *
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
17 */
18
19 #include <config.h>
20 #include "d3d8_private.h"
21
22 WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
23
24 static inline struct d3d8_vertexbuffer *impl_from_IDirect3DVertexBuffer8(IDirect3DVertexBuffer8 *iface)
25 {
26 return CONTAINING_RECORD(iface, struct d3d8_vertexbuffer, IDirect3DVertexBuffer8_iface);
27 }
28
29 static HRESULT WINAPI d3d8_vertexbuffer_QueryInterface(IDirect3DVertexBuffer8 *iface, REFIID riid, void **object)
30 {
31 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
32
33 if (IsEqualGUID(riid, &IID_IDirect3DVertexBuffer8)
34 || IsEqualGUID(riid, &IID_IDirect3DResource8)
35 || IsEqualGUID(riid, &IID_IUnknown))
36 {
37 IUnknown_AddRef(iface);
38 *object = iface;
39 return S_OK;
40 }
41
42 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
43
44 *object = NULL;
45 return E_NOINTERFACE;
46 }
47
48 static ULONG WINAPI d3d8_vertexbuffer_AddRef(IDirect3DVertexBuffer8 *iface)
49 {
50 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
51 ULONG refcount = InterlockedIncrement(&buffer->refcount);
52
53 TRACE("%p increasing refcount to %u.\n", iface, refcount);
54
55 if (refcount == 1)
56 {
57 IDirect3DDevice8_AddRef(buffer->parent_device);
58 wined3d_mutex_lock();
59 wined3d_buffer_incref(buffer->wined3d_buffer);
60 wined3d_mutex_unlock();
61 }
62
63 return refcount;
64 }
65
66 static ULONG WINAPI d3d8_vertexbuffer_Release(IDirect3DVertexBuffer8 *iface)
67 {
68 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
69 ULONG refcount = InterlockedDecrement(&buffer->refcount);
70
71 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
72
73 if (!refcount)
74 {
75 IDirect3DDevice8 *device = buffer->parent_device;
76
77 wined3d_mutex_lock();
78 wined3d_buffer_decref(buffer->wined3d_buffer);
79 wined3d_mutex_unlock();
80
81 /* Release the device last, as it may cause the device to be destroyed. */
82 IDirect3DDevice8_Release(device);
83 }
84
85 return refcount;
86 }
87
88 static HRESULT WINAPI d3d8_vertexbuffer_GetDevice(IDirect3DVertexBuffer8 *iface,
89 IDirect3DDevice8 **device)
90 {
91 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
92
93 TRACE("iface %p, device %p.\n", iface, device);
94
95 *device = buffer->parent_device;
96 IDirect3DDevice8_AddRef(*device);
97
98 TRACE("Returning device %p.\n", *device);
99
100 return D3D_OK;
101 }
102
103 static HRESULT WINAPI d3d8_vertexbuffer_SetPrivateData(IDirect3DVertexBuffer8 *iface,
104 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
105 {
106 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
107 struct wined3d_resource *resource;
108 HRESULT hr;
109
110 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
111 iface, debugstr_guid(guid), data, data_size, flags);
112
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();
117
118 return hr;
119 }
120
121 static HRESULT WINAPI d3d8_vertexbuffer_GetPrivateData(IDirect3DVertexBuffer8 *iface,
122 REFGUID guid, void *data, DWORD *data_size)
123 {
124 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
125 struct wined3d_resource *resource;
126 HRESULT hr;
127
128 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
129 iface, debugstr_guid(guid), data, data_size);
130
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();
135
136 return hr;
137 }
138
139 static HRESULT WINAPI d3d8_vertexbuffer_FreePrivateData(IDirect3DVertexBuffer8 *iface, REFGUID guid)
140 {
141 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
142 struct wined3d_resource *resource;
143 HRESULT hr;
144
145 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
146
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();
151
152 return hr;
153 }
154
155 static DWORD WINAPI d3d8_vertexbuffer_SetPriority(IDirect3DVertexBuffer8 *iface, DWORD priority)
156 {
157 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
158 DWORD previous;
159
160 TRACE("iface %p, priority %u.\n", iface, priority);
161
162 wined3d_mutex_lock();
163 previous = wined3d_buffer_set_priority(buffer->wined3d_buffer, priority);
164 wined3d_mutex_unlock();
165
166 return previous;
167 }
168
169 static DWORD WINAPI d3d8_vertexbuffer_GetPriority(IDirect3DVertexBuffer8 *iface)
170 {
171 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
172 DWORD priority;
173
174 TRACE("iface %p.\n", iface);
175
176 wined3d_mutex_lock();
177 priority = wined3d_buffer_get_priority(buffer->wined3d_buffer);
178 wined3d_mutex_unlock();
179
180 return priority;
181 }
182
183 static void WINAPI d3d8_vertexbuffer_PreLoad(IDirect3DVertexBuffer8 *iface)
184 {
185 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
186
187 TRACE("iface %p.\n", iface);
188
189 wined3d_mutex_lock();
190 wined3d_buffer_preload(buffer->wined3d_buffer);
191 wined3d_mutex_unlock();
192 }
193
194 static D3DRESOURCETYPE WINAPI d3d8_vertexbuffer_GetType(IDirect3DVertexBuffer8 *iface)
195 {
196 TRACE("iface %p.\n", iface);
197
198 return D3DRTYPE_VERTEXBUFFER;
199 }
200
201 static HRESULT WINAPI d3d8_vertexbuffer_Lock(IDirect3DVertexBuffer8 *iface, UINT offset, UINT size,
202 BYTE **data, DWORD flags)
203 {
204 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
205 HRESULT hr;
206
207 TRACE("iface %p, offset %u, size %u, data %p, flags %#x.\n",
208 iface, offset, size, data, flags);
209
210 wined3d_mutex_lock();
211 hr = wined3d_buffer_map(buffer->wined3d_buffer, offset, size, data, flags);
212 wined3d_mutex_unlock();
213
214 return hr;
215 }
216
217 static HRESULT WINAPI d3d8_vertexbuffer_Unlock(IDirect3DVertexBuffer8 *iface)
218 {
219 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
220
221 TRACE("iface %p.\n", iface);
222
223 wined3d_mutex_lock();
224 wined3d_buffer_unmap(buffer->wined3d_buffer);
225 wined3d_mutex_unlock();
226
227 return D3D_OK;
228 }
229
230 static HRESULT WINAPI d3d8_vertexbuffer_GetDesc(IDirect3DVertexBuffer8 *iface,
231 D3DVERTEXBUFFER_DESC *desc)
232 {
233 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
234 struct wined3d_resource_desc wined3d_desc;
235 struct wined3d_resource *wined3d_resource;
236
237 TRACE("iface %p, desc %p.\n", iface, desc);
238
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();
243
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;
250
251 return D3D_OK;
252 }
253
254 static const IDirect3DVertexBuffer8Vtbl Direct3DVertexBuffer8_Vtbl =
255 {
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,
273 };
274
275 static void STDMETHODCALLTYPE d3d8_vertexbuffer_wined3d_object_destroyed(void *parent)
276 {
277 HeapFree(GetProcessHeap(), 0, parent);
278 }
279
280 static const struct wined3d_parent_ops d3d8_vertexbuffer_wined3d_parent_ops =
281 {
282 d3d8_vertexbuffer_wined3d_object_destroyed,
283 };
284
285 HRESULT vertexbuffer_init(struct d3d8_vertexbuffer *buffer, struct d3d8_device *device,
286 UINT size, DWORD usage, DWORD fvf, D3DPOOL pool)
287 {
288 HRESULT hr;
289
290 buffer->IDirect3DVertexBuffer8_iface.lpVtbl = &Direct3DVertexBuffer8_Vtbl;
291 buffer->refcount = 1;
292 buffer->fvf = fvf;
293
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))
299 {
300 WARN("Failed to create wined3d buffer, hr %#x.\n", hr);
301 return hr;
302 }
303
304 buffer->parent_device = &device->IDirect3DDevice8_iface;
305 IUnknown_AddRef(buffer->parent_device);
306
307 return D3D_OK;
308 }
309
310 struct d3d8_vertexbuffer *unsafe_impl_from_IDirect3DVertexBuffer8(IDirect3DVertexBuffer8 *iface)
311 {
312 if (!iface)
313 return NULL;
314 assert(iface->lpVtbl == &Direct3DVertexBuffer8_Vtbl);
315
316 return impl_from_IDirect3DVertexBuffer8(iface);
317 }
318
319 static inline struct d3d8_indexbuffer *impl_from_IDirect3DIndexBuffer8(IDirect3DIndexBuffer8 *iface)
320 {
321 return CONTAINING_RECORD(iface, struct d3d8_indexbuffer, IDirect3DIndexBuffer8_iface);
322 }
323
324 static HRESULT WINAPI d3d8_indexbuffer_QueryInterface(IDirect3DIndexBuffer8 *iface, REFIID riid, void **object)
325 {
326 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
327
328 if (IsEqualGUID(riid, &IID_IDirect3DIndexBuffer8)
329 || IsEqualGUID(riid, &IID_IDirect3DResource8)
330 || IsEqualGUID(riid, &IID_IUnknown))
331 {
332 IUnknown_AddRef(iface);
333 *object = iface;
334 return S_OK;
335 }
336
337 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
338
339 *object = NULL;
340 return E_NOINTERFACE;
341 }
342
343 static ULONG WINAPI d3d8_indexbuffer_AddRef(IDirect3DIndexBuffer8 *iface)
344 {
345 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
346 ULONG refcount = InterlockedIncrement(&buffer->refcount);
347
348 TRACE("%p increasing refcount to %u.\n", iface, refcount);
349
350 if (refcount == 1)
351 {
352 IDirect3DDevice8_AddRef(buffer->parent_device);
353 wined3d_mutex_lock();
354 wined3d_buffer_incref(buffer->wined3d_buffer);
355 wined3d_mutex_unlock();
356 }
357
358 return refcount;
359 }
360
361 static ULONG WINAPI d3d8_indexbuffer_Release(IDirect3DIndexBuffer8 *iface)
362 {
363 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
364 ULONG refcount = InterlockedDecrement(&buffer->refcount);
365
366 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
367
368 if (!refcount)
369 {
370 IDirect3DDevice8 *device = buffer->parent_device;
371
372 wined3d_mutex_lock();
373 wined3d_buffer_decref(buffer->wined3d_buffer);
374 wined3d_mutex_unlock();
375
376 /* Release the device last, as it may cause the device to be destroyed. */
377 IDirect3DDevice8_Release(device);
378 }
379
380 return refcount;
381 }
382
383 static HRESULT WINAPI d3d8_indexbuffer_GetDevice(IDirect3DIndexBuffer8 *iface,
384 IDirect3DDevice8 **device)
385 {
386 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
387
388 TRACE("iface %p, device %p.\n", iface, device);
389
390 *device = buffer->parent_device;
391 IDirect3DDevice8_AddRef(*device);
392
393 TRACE("Returning device %p.\n", *device);
394
395 return D3D_OK;
396 }
397
398 static HRESULT WINAPI d3d8_indexbuffer_SetPrivateData(IDirect3DIndexBuffer8 *iface,
399 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
400 {
401 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
402 struct wined3d_resource *resource;
403 HRESULT hr;
404
405 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
406 iface, debugstr_guid(guid), data, data_size, flags);
407
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();
412
413 return hr;
414 }
415
416 static HRESULT WINAPI d3d8_indexbuffer_GetPrivateData(IDirect3DIndexBuffer8 *iface,
417 REFGUID guid, void *data, DWORD *data_size)
418 {
419 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
420 struct wined3d_resource *resource;
421 HRESULT hr;
422
423 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
424 iface, debugstr_guid(guid), data, data_size);
425
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();
430
431 return hr;
432 }
433
434 static HRESULT WINAPI d3d8_indexbuffer_FreePrivateData(IDirect3DIndexBuffer8 *iface, REFGUID guid)
435 {
436 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
437 struct wined3d_resource *resource;
438 HRESULT hr;
439
440 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
441
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();
446
447 return hr;
448 }
449
450 static DWORD WINAPI d3d8_indexbuffer_SetPriority(IDirect3DIndexBuffer8 *iface, DWORD priority)
451 {
452 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
453 DWORD previous;
454
455 TRACE("iface %p, priority %u.\n", iface, priority);
456
457 wined3d_mutex_lock();
458 previous = wined3d_buffer_set_priority(buffer->wined3d_buffer, priority);
459 wined3d_mutex_unlock();
460
461 return previous;
462 }
463
464 static DWORD WINAPI d3d8_indexbuffer_GetPriority(IDirect3DIndexBuffer8 *iface)
465 {
466 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
467 DWORD priority;
468
469 TRACE("iface %p.\n", iface);
470
471 wined3d_mutex_lock();
472 priority = wined3d_buffer_get_priority(buffer->wined3d_buffer);
473 wined3d_mutex_unlock();
474
475 return priority;
476 }
477
478 static void WINAPI d3d8_indexbuffer_PreLoad(IDirect3DIndexBuffer8 *iface)
479 {
480 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
481
482 TRACE("iface %p.\n", iface);
483
484 wined3d_mutex_lock();
485 wined3d_buffer_preload(buffer->wined3d_buffer);
486 wined3d_mutex_unlock();
487 }
488
489 static D3DRESOURCETYPE WINAPI d3d8_indexbuffer_GetType(IDirect3DIndexBuffer8 *iface)
490 {
491 TRACE("iface %p.\n", iface);
492
493 return D3DRTYPE_INDEXBUFFER;
494 }
495
496 static HRESULT WINAPI d3d8_indexbuffer_Lock(IDirect3DIndexBuffer8 *iface, UINT offset, UINT size,
497 BYTE **data, DWORD flags)
498 {
499 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
500 HRESULT hr;
501
502 TRACE("iface %p, offset %u, size %u, data %p, flags %#x.\n",
503 iface, offset, size, data, flags);
504
505 wined3d_mutex_lock();
506 hr = wined3d_buffer_map(buffer->wined3d_buffer, offset, size, data, flags);
507 wined3d_mutex_unlock();
508
509 return hr;
510 }
511
512 static HRESULT WINAPI d3d8_indexbuffer_Unlock(IDirect3DIndexBuffer8 *iface)
513 {
514 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
515
516 TRACE("iface %p.\n", iface);
517
518 wined3d_mutex_lock();
519 wined3d_buffer_unmap(buffer->wined3d_buffer);
520 wined3d_mutex_unlock();
521
522 return D3D_OK;
523 }
524
525 static HRESULT WINAPI d3d8_indexbuffer_GetDesc(IDirect3DIndexBuffer8 *iface,
526 D3DINDEXBUFFER_DESC *desc)
527 {
528 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
529 struct wined3d_resource_desc wined3d_desc;
530 struct wined3d_resource *wined3d_resource;
531
532 TRACE("iface %p, desc %p.\n", iface, desc);
533
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();
538
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;
544
545 return D3D_OK;
546 }
547
548 static const IDirect3DIndexBuffer8Vtbl d3d8_indexbuffer_vtbl =
549 {
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,
567 };
568
569 static void STDMETHODCALLTYPE d3d8_indexbuffer_wined3d_object_destroyed(void *parent)
570 {
571 HeapFree(GetProcessHeap(), 0, parent);
572 }
573
574 static const struct wined3d_parent_ops d3d8_indexbuffer_wined3d_parent_ops =
575 {
576 d3d8_indexbuffer_wined3d_object_destroyed,
577 };
578
579 HRESULT indexbuffer_init(struct d3d8_indexbuffer *buffer, struct d3d8_device *device,
580 UINT size, DWORD usage, D3DFORMAT format, D3DPOOL pool)
581 {
582 HRESULT hr;
583
584 buffer->IDirect3DIndexBuffer8_iface.lpVtbl = &d3d8_indexbuffer_vtbl;
585 buffer->refcount = 1;
586 buffer->format = wined3dformat_from_d3dformat(format);
587
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))
593 {
594 WARN("Failed to create wined3d buffer, hr %#x.\n", hr);
595 return hr;
596 }
597
598 buffer->parent_device = &device->IDirect3DDevice8_iface;
599 IUnknown_AddRef(buffer->parent_device);
600
601 return D3D_OK;
602 }
603
604 struct d3d8_indexbuffer *unsafe_impl_from_IDirect3DIndexBuffer8(IDirect3DIndexBuffer8 *iface)
605 {
606 if (!iface)
607 return NULL;
608 assert(iface->lpVtbl == &d3d8_indexbuffer_vtbl);
609
610 return impl_from_IDirect3DIndexBuffer8(iface);
611 }