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