d3d8: Use unsafe_impl_from_IDirect3DIndexBuffer8 for an app provided iface.
[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, lpVtbl);
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 = (IDirect3DVertexBuffer8Impl *)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 = (IDirect3DVertexBuffer8Impl *)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, IDirect3DDevice8 **device)
90 {
91     TRACE("iface %p, device %p.\n", iface, device);
92
93     *device = (IDirect3DDevice8 *)((IDirect3DVertexBuffer8Impl *)iface)->parentDevice;
94     IDirect3DDevice8_AddRef(*device);
95
96     TRACE("Returning device %p.\n", *device);
97
98     return D3D_OK;
99 }
100
101 static HRESULT WINAPI d3d8_vertexbuffer_SetPrivateData(IDirect3DVertexBuffer8 *iface,
102         REFGUID guid, const void *data, DWORD data_size, DWORD flags)
103 {
104     IDirect3DVertexBuffer8Impl *buffer = impl_from_IDirect3DVertexBuffer8(iface);
105     struct wined3d_resource *resource;
106     HRESULT hr;
107
108     TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
109             iface, debugstr_guid(guid), data, data_size, flags);
110
111     wined3d_mutex_lock();
112     resource = wined3d_buffer_get_resource(buffer->wineD3DVertexBuffer);
113     hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
114     wined3d_mutex_unlock();
115
116     return hr;
117 }
118
119 static HRESULT WINAPI d3d8_vertexbuffer_GetPrivateData(IDirect3DVertexBuffer8 *iface,
120         REFGUID guid, void *data, DWORD *data_size)
121 {
122     IDirect3DVertexBuffer8Impl *buffer = impl_from_IDirect3DVertexBuffer8(iface);
123     struct wined3d_resource *resource;
124     HRESULT hr;
125
126     TRACE("iface %p, guid %s, data %p, data_size %p.\n",
127             iface, debugstr_guid(guid), data, data_size);
128
129     wined3d_mutex_lock();
130     resource = wined3d_buffer_get_resource(buffer->wineD3DVertexBuffer);
131     hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
132     wined3d_mutex_unlock();
133
134     return hr;
135 }
136
137 static HRESULT WINAPI d3d8_vertexbuffer_FreePrivateData(IDirect3DVertexBuffer8 *iface, REFGUID guid)
138 {
139     IDirect3DVertexBuffer8Impl *buffer = impl_from_IDirect3DVertexBuffer8(iface);
140     struct wined3d_resource *resource;
141     HRESULT hr;
142
143     TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
144
145     wined3d_mutex_lock();
146     resource = wined3d_buffer_get_resource(buffer->wineD3DVertexBuffer);
147     hr = wined3d_resource_free_private_data(resource, guid);
148     wined3d_mutex_unlock();
149
150     return hr;
151 }
152
153 static DWORD WINAPI d3d8_vertexbuffer_SetPriority(IDirect3DVertexBuffer8 *iface, DWORD priority)
154 {
155     DWORD previous;
156
157     TRACE("iface %p, priority %u.\n", iface, priority);
158
159     wined3d_mutex_lock();
160     previous = wined3d_buffer_set_priority(((IDirect3DVertexBuffer8Impl *)iface)->wineD3DVertexBuffer, priority);
161     wined3d_mutex_unlock();
162
163     return previous;
164 }
165
166 static DWORD WINAPI d3d8_vertexbuffer_GetPriority(IDirect3DVertexBuffer8 *iface)
167 {
168     DWORD priority;
169
170     TRACE("iface %p.\n", iface);
171
172     wined3d_mutex_lock();
173     priority = wined3d_buffer_get_priority(((IDirect3DVertexBuffer8Impl *)iface)->wineD3DVertexBuffer);
174     wined3d_mutex_unlock();
175
176     return priority;
177 }
178
179 static void WINAPI d3d8_vertexbuffer_PreLoad(IDirect3DVertexBuffer8 *iface)
180 {
181     TRACE("iface %p.\n", iface);
182
183     wined3d_mutex_lock();
184     wined3d_buffer_preload(((IDirect3DVertexBuffer8Impl *)iface)->wineD3DVertexBuffer);
185     wined3d_mutex_unlock();
186 }
187
188 static D3DRESOURCETYPE WINAPI d3d8_vertexbuffer_GetType(IDirect3DVertexBuffer8 *iface)
189 {
190     TRACE("iface %p.\n", iface);
191
192     return D3DRTYPE_VERTEXBUFFER;
193 }
194
195 static HRESULT WINAPI d3d8_vertexbuffer_Lock(IDirect3DVertexBuffer8 *iface,
196         UINT offset, UINT size, BYTE **data, DWORD flags)
197 {
198     HRESULT hr;
199
200     TRACE("iface %p, offset %u, size %u, data %p, flags %#x.\n",
201             iface, offset, size, data, flags);
202
203     wined3d_mutex_lock();
204     hr = wined3d_buffer_map(((IDirect3DVertexBuffer8Impl *)iface)->wineD3DVertexBuffer,
205             offset, size, data, flags);
206     wined3d_mutex_unlock();
207
208     return hr;
209 }
210
211 static HRESULT WINAPI d3d8_vertexbuffer_Unlock(IDirect3DVertexBuffer8 *iface)
212 {
213     TRACE("iface %p.\n", iface);
214
215     wined3d_mutex_lock();
216     wined3d_buffer_unmap(((IDirect3DVertexBuffer8Impl *)iface)->wineD3DVertexBuffer);
217     wined3d_mutex_unlock();
218
219     return D3D_OK;
220 }
221
222 static HRESULT WINAPI d3d8_vertexbuffer_GetDesc(IDirect3DVertexBuffer8 *iface, D3DVERTEXBUFFER_DESC *desc)
223 {
224     IDirect3DVertexBuffer8Impl *buffer = (IDirect3DVertexBuffer8Impl *)iface;
225     struct wined3d_resource_desc wined3d_desc;
226     struct wined3d_resource *wined3d_resource;
227
228     TRACE("iface %p, desc %p.\n", iface, desc);
229
230     wined3d_mutex_lock();
231     wined3d_resource = wined3d_buffer_get_resource(buffer->wineD3DVertexBuffer);
232     wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
233     wined3d_mutex_unlock();
234
235     desc->Type = D3DRTYPE_VERTEXBUFFER;
236     desc->Usage = wined3d_desc.usage;
237     desc->Pool = wined3d_desc.pool;
238     desc->Size = wined3d_desc.size;
239     desc->FVF = buffer->fvf;
240     desc->Format = D3DFMT_VERTEXDATA;
241
242     return D3D_OK;
243 }
244
245 static const IDirect3DVertexBuffer8Vtbl Direct3DVertexBuffer8_Vtbl =
246 {
247     /* IUnknown */
248     d3d8_vertexbuffer_QueryInterface,
249     d3d8_vertexbuffer_AddRef,
250     d3d8_vertexbuffer_Release,
251     /* IDirect3DResource8 */
252     d3d8_vertexbuffer_GetDevice,
253     d3d8_vertexbuffer_SetPrivateData,
254     d3d8_vertexbuffer_GetPrivateData,
255     d3d8_vertexbuffer_FreePrivateData,
256     d3d8_vertexbuffer_SetPriority,
257     d3d8_vertexbuffer_GetPriority,
258     d3d8_vertexbuffer_PreLoad,
259     d3d8_vertexbuffer_GetType,
260     /* IDirect3DVertexBuffer8 */
261     d3d8_vertexbuffer_Lock,
262     d3d8_vertexbuffer_Unlock,
263     d3d8_vertexbuffer_GetDesc,
264 };
265
266 static void STDMETHODCALLTYPE d3d8_vertexbuffer_wined3d_object_destroyed(void *parent)
267 {
268     HeapFree(GetProcessHeap(), 0, parent);
269 }
270
271 static const struct wined3d_parent_ops d3d8_vertexbuffer_wined3d_parent_ops =
272 {
273     d3d8_vertexbuffer_wined3d_object_destroyed,
274 };
275
276 HRESULT vertexbuffer_init(IDirect3DVertexBuffer8Impl *buffer, IDirect3DDevice8Impl *device,
277         UINT size, DWORD usage, DWORD fvf, D3DPOOL pool)
278 {
279     HRESULT hr;
280
281     buffer->lpVtbl = &Direct3DVertexBuffer8_Vtbl;
282     buffer->ref = 1;
283     buffer->fvf = fvf;
284
285     wined3d_mutex_lock();
286     hr = wined3d_buffer_create_vb(device->wined3d_device, size, usage & WINED3DUSAGE_MASK,
287             (WINED3DPOOL)pool, buffer, &d3d8_vertexbuffer_wined3d_parent_ops, &buffer->wineD3DVertexBuffer);
288     wined3d_mutex_unlock();
289     if (FAILED(hr))
290     {
291         WARN("Failed to create wined3d buffer, hr %#x.\n", hr);
292         return hr;
293     }
294
295     buffer->parentDevice = &device->IDirect3DDevice8_iface;
296     IUnknown_AddRef(buffer->parentDevice);
297
298     return D3D_OK;
299 }
300
301 static inline IDirect3DIndexBuffer8Impl *impl_from_IDirect3DIndexBuffer8(IDirect3DIndexBuffer8 *iface)
302 {
303     return CONTAINING_RECORD(iface, IDirect3DIndexBuffer8Impl, lpVtbl);
304 }
305
306 static HRESULT WINAPI d3d8_indexbuffer_QueryInterface(IDirect3DIndexBuffer8 *iface, REFIID riid, void **object)
307 {
308     TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
309
310     if (IsEqualGUID(riid, &IID_IDirect3DIndexBuffer8)
311             || IsEqualGUID(riid, &IID_IDirect3DResource8)
312             || IsEqualGUID(riid, &IID_IUnknown))
313     {
314         IUnknown_AddRef(iface);
315         *object = iface;
316         return S_OK;
317     }
318
319     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
320
321     *object = NULL;
322     return E_NOINTERFACE;
323 }
324
325 static ULONG WINAPI d3d8_indexbuffer_AddRef(IDirect3DIndexBuffer8 *iface)
326 {
327     IDirect3DIndexBuffer8Impl *buffer = (IDirect3DIndexBuffer8Impl *)iface;
328     ULONG refcount = InterlockedIncrement(&buffer->ref);
329
330     TRACE("%p increasing refcount to %u.\n", iface, refcount);
331
332     if (refcount == 1)
333     {
334         IDirect3DDevice8_AddRef(buffer->parentDevice);
335         wined3d_mutex_lock();
336         wined3d_buffer_incref(buffer->wineD3DIndexBuffer);
337         wined3d_mutex_unlock();
338     }
339
340     return refcount;
341 }
342
343 static ULONG WINAPI d3d8_indexbuffer_Release(IDirect3DIndexBuffer8 *iface)
344 {
345     IDirect3DIndexBuffer8Impl *buffer = (IDirect3DIndexBuffer8Impl *)iface;
346     ULONG refcount = InterlockedDecrement(&buffer->ref);
347
348     TRACE("%p decreasing refcount to %u.\n", iface, refcount);
349
350     if (!refcount)
351     {
352         IDirect3DDevice8 *device = buffer->parentDevice;
353
354         wined3d_mutex_lock();
355         wined3d_buffer_decref(buffer->wineD3DIndexBuffer);
356         wined3d_mutex_unlock();
357
358         /* Release the device last, as it may cause the device to be destroyed. */
359         IDirect3DDevice8_Release(device);
360     }
361
362     return refcount;
363 }
364
365 static HRESULT WINAPI d3d8_indexbuffer_GetDevice(IDirect3DIndexBuffer8 *iface, IDirect3DDevice8 **device)
366 {
367     TRACE("iface %p, device %p.\n", iface, device);
368
369     *device = (IDirect3DDevice8 *)((IDirect3DIndexBuffer8Impl *)iface)->parentDevice;
370     IDirect3DDevice8_AddRef(*device);
371
372     TRACE("Returning device %p.\n", *device);
373
374     return D3D_OK;
375 }
376
377 static HRESULT WINAPI d3d8_indexbuffer_SetPrivateData(IDirect3DIndexBuffer8 *iface,
378         REFGUID guid, const void *data, DWORD data_size, DWORD flags)
379 {
380     IDirect3DIndexBuffer8Impl *buffer = impl_from_IDirect3DIndexBuffer8(iface);
381     struct wined3d_resource *resource;
382     HRESULT hr;
383
384     TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
385             iface, debugstr_guid(guid), data, data_size, flags);
386
387     wined3d_mutex_lock();
388     resource = wined3d_buffer_get_resource(buffer->wineD3DIndexBuffer);
389     hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
390     wined3d_mutex_unlock();
391
392     return hr;
393 }
394
395 static HRESULT WINAPI d3d8_indexbuffer_GetPrivateData(IDirect3DIndexBuffer8 *iface,
396         REFGUID guid, void *data, DWORD *data_size)
397 {
398     IDirect3DIndexBuffer8Impl *buffer = impl_from_IDirect3DIndexBuffer8(iface);
399     struct wined3d_resource *resource;
400     HRESULT hr;
401
402     TRACE("iface %p, guid %s, data %p, data_size %p.\n",
403             iface, debugstr_guid(guid), data, data_size);
404
405     wined3d_mutex_lock();
406     resource = wined3d_buffer_get_resource(buffer->wineD3DIndexBuffer);
407     hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
408     wined3d_mutex_unlock();
409
410     return hr;
411 }
412
413 static HRESULT WINAPI d3d8_indexbuffer_FreePrivateData(IDirect3DIndexBuffer8 *iface, REFGUID guid)
414 {
415     IDirect3DIndexBuffer8Impl *buffer = impl_from_IDirect3DIndexBuffer8(iface);
416     struct wined3d_resource *resource;
417     HRESULT hr;
418
419     TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
420
421     wined3d_mutex_lock();
422     resource = wined3d_buffer_get_resource(buffer->wineD3DIndexBuffer);
423     hr = wined3d_resource_free_private_data(resource, guid);
424     wined3d_mutex_unlock();
425
426     return hr;
427 }
428
429 static DWORD WINAPI d3d8_indexbuffer_SetPriority(IDirect3DIndexBuffer8 *iface, DWORD priority)
430 {
431     DWORD previous;
432
433     TRACE("iface %p, priority %u.\n", iface, priority);
434
435     wined3d_mutex_lock();
436     previous = wined3d_buffer_set_priority(((IDirect3DIndexBuffer8Impl *)iface)->wineD3DIndexBuffer, priority);
437     wined3d_mutex_unlock();
438
439     return previous;
440 }
441
442 static DWORD WINAPI d3d8_indexbuffer_GetPriority(IDirect3DIndexBuffer8 *iface)
443 {
444     DWORD priority;
445
446     TRACE("iface %p.\n", iface);
447
448     wined3d_mutex_lock();
449     priority = wined3d_buffer_get_priority(((IDirect3DIndexBuffer8Impl *)iface)->wineD3DIndexBuffer);
450     wined3d_mutex_unlock();
451
452     return priority;
453 }
454
455 static void WINAPI d3d8_indexbuffer_PreLoad(IDirect3DIndexBuffer8 *iface)
456 {
457     TRACE("iface %p.\n", iface);
458
459     wined3d_mutex_lock();
460     wined3d_buffer_preload(((IDirect3DIndexBuffer8Impl *)iface)->wineD3DIndexBuffer);
461     wined3d_mutex_unlock();
462 }
463
464 static D3DRESOURCETYPE WINAPI d3d8_indexbuffer_GetType(IDirect3DIndexBuffer8 *iface)
465 {
466     TRACE("iface %p.\n", iface);
467
468     return D3DRTYPE_INDEXBUFFER;
469 }
470
471 static HRESULT WINAPI d3d8_indexbuffer_Lock(IDirect3DIndexBuffer8 *iface,
472         UINT offset, UINT size, BYTE **data, DWORD flags)
473 {
474     HRESULT hr;
475
476     TRACE("iface %p, offset %u, size %u, data %p, flags %#x.\n",
477             iface, offset, size, data, flags);
478
479     wined3d_mutex_lock();
480     hr = wined3d_buffer_map(((IDirect3DIndexBuffer8Impl *)iface)->wineD3DIndexBuffer,
481             offset, size, data, flags);
482     wined3d_mutex_unlock();
483
484     return hr;
485 }
486
487 static HRESULT WINAPI d3d8_indexbuffer_Unlock(IDirect3DIndexBuffer8 *iface)
488 {
489     TRACE("iface %p.\n", iface);
490
491     wined3d_mutex_lock();
492     wined3d_buffer_unmap(((IDirect3DIndexBuffer8Impl *)iface)->wineD3DIndexBuffer);
493     wined3d_mutex_unlock();
494
495     return D3D_OK;
496 }
497
498 static HRESULT WINAPI d3d8_indexbuffer_GetDesc(IDirect3DIndexBuffer8 *iface, D3DINDEXBUFFER_DESC *desc)
499 {
500     IDirect3DIndexBuffer8Impl *buffer = (IDirect3DIndexBuffer8Impl *)iface;
501     struct wined3d_resource_desc wined3d_desc;
502     struct wined3d_resource *wined3d_resource;
503
504     TRACE("iface %p, desc %p.\n", iface, desc);
505
506     wined3d_mutex_lock();
507     wined3d_resource = wined3d_buffer_get_resource(buffer->wineD3DIndexBuffer);
508     wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
509     wined3d_mutex_unlock();
510
511     desc->Format = d3dformat_from_wined3dformat(buffer->format);
512     desc->Type = D3DRTYPE_INDEXBUFFER;
513     desc->Usage = wined3d_desc.usage;
514     desc->Pool = wined3d_desc.pool;
515     desc->Size = wined3d_desc.size;
516
517     return D3D_OK;
518 }
519
520 static const IDirect3DIndexBuffer8Vtbl d3d8_indexbuffer_vtbl =
521 {
522     /* IUnknown */
523     d3d8_indexbuffer_QueryInterface,
524     d3d8_indexbuffer_AddRef,
525     d3d8_indexbuffer_Release,
526     /* IDirect3DResource8 */
527     d3d8_indexbuffer_GetDevice,
528     d3d8_indexbuffer_SetPrivateData,
529     d3d8_indexbuffer_GetPrivateData,
530     d3d8_indexbuffer_FreePrivateData,
531     d3d8_indexbuffer_SetPriority,
532     d3d8_indexbuffer_GetPriority,
533     d3d8_indexbuffer_PreLoad,
534     d3d8_indexbuffer_GetType,
535     /* IDirect3DIndexBuffer8 */
536     d3d8_indexbuffer_Lock,
537     d3d8_indexbuffer_Unlock,
538     d3d8_indexbuffer_GetDesc,
539 };
540
541 static void STDMETHODCALLTYPE d3d8_indexbuffer_wined3d_object_destroyed(void *parent)
542 {
543     HeapFree(GetProcessHeap(), 0, parent);
544 }
545
546 static const struct wined3d_parent_ops d3d8_indexbuffer_wined3d_parent_ops =
547 {
548     d3d8_indexbuffer_wined3d_object_destroyed,
549 };
550
551 HRESULT indexbuffer_init(IDirect3DIndexBuffer8Impl *buffer, IDirect3DDevice8Impl *device,
552         UINT size, DWORD usage, D3DFORMAT format, D3DPOOL pool)
553 {
554     HRESULT hr;
555
556     buffer->lpVtbl = &d3d8_indexbuffer_vtbl;
557     buffer->ref = 1;
558     buffer->format = wined3dformat_from_d3dformat(format);
559
560     wined3d_mutex_lock();
561     hr = wined3d_buffer_create_ib(device->wined3d_device, size, usage & WINED3DUSAGE_MASK,
562             (WINED3DPOOL)pool, buffer, &d3d8_indexbuffer_wined3d_parent_ops, &buffer->wineD3DIndexBuffer);
563     wined3d_mutex_unlock();
564     if (FAILED(hr))
565     {
566         WARN("Failed to create wined3d buffer, hr %#x.\n", hr);
567         return hr;
568     }
569
570     buffer->parentDevice = &device->IDirect3DDevice8_iface;
571     IUnknown_AddRef(buffer->parentDevice);
572
573     return D3D_OK;
574 }
575
576 IDirect3DIndexBuffer8Impl *unsafe_impl_from_IDirect3DIndexBuffer8(IDirect3DIndexBuffer8 *iface)
577 {
578     if (!iface)
579         return NULL;
580     assert(iface->lpVtbl == &d3d8_indexbuffer_vtbl);
581
582     return impl_from_IDirect3DIndexBuffer8(iface);
583 }