ntoskrnl.exe/tests: Fix path buffer allocation size.
[wine.git] / dlls / d3d8 / buffer.c
blob3b980003b310ce77420abb2bed660c7f52f699ad
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 IDirect3DVertexBuffer8_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->resource.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 if (buffer->draw_buffer)
61 wined3d_buffer_incref(buffer->draw_buffer);
62 wined3d_mutex_unlock();
65 return refcount;
68 static ULONG WINAPI d3d8_vertexbuffer_Release(IDirect3DVertexBuffer8 *iface)
70 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
71 ULONG refcount = InterlockedDecrement(&buffer->resource.refcount);
73 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
75 if (!refcount)
77 struct wined3d_buffer *draw_buffer = buffer->draw_buffer;
78 IDirect3DDevice8 *device = buffer->parent_device;
80 wined3d_mutex_lock();
81 wined3d_buffer_decref(buffer->wined3d_buffer);
82 if (draw_buffer)
83 wined3d_buffer_decref(draw_buffer);
84 wined3d_mutex_unlock();
86 /* Release the device last, as it may cause the device to be destroyed. */
87 IDirect3DDevice8_Release(device);
90 return refcount;
93 static HRESULT WINAPI d3d8_vertexbuffer_GetDevice(IDirect3DVertexBuffer8 *iface,
94 IDirect3DDevice8 **device)
96 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
98 TRACE("iface %p, device %p.\n", iface, device);
100 *device = buffer->parent_device;
101 IDirect3DDevice8_AddRef(*device);
103 TRACE("Returning device %p.\n", *device);
105 return D3D_OK;
108 static HRESULT WINAPI d3d8_vertexbuffer_SetPrivateData(IDirect3DVertexBuffer8 *iface,
109 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
111 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
112 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
113 iface, debugstr_guid(guid), data, data_size, flags);
115 return d3d8_resource_set_private_data(&buffer->resource, guid, data, data_size, flags);
118 static HRESULT WINAPI d3d8_vertexbuffer_GetPrivateData(IDirect3DVertexBuffer8 *iface,
119 REFGUID guid, void *data, DWORD *data_size)
121 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
122 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
123 iface, debugstr_guid(guid), data, data_size);
125 return d3d8_resource_get_private_data(&buffer->resource, guid, data, data_size);
128 static HRESULT WINAPI d3d8_vertexbuffer_FreePrivateData(IDirect3DVertexBuffer8 *iface, REFGUID guid)
130 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
131 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
133 return d3d8_resource_free_private_data(&buffer->resource, guid);
136 static DWORD WINAPI d3d8_vertexbuffer_SetPriority(IDirect3DVertexBuffer8 *iface, DWORD priority)
138 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
139 struct wined3d_resource *resource;
140 DWORD previous;
142 TRACE("iface %p, priority %u.\n", iface, priority);
144 wined3d_mutex_lock();
145 resource = wined3d_buffer_get_resource(buffer->wined3d_buffer);
146 previous = wined3d_resource_set_priority(resource, priority);
147 wined3d_mutex_unlock();
149 return previous;
152 static DWORD WINAPI d3d8_vertexbuffer_GetPriority(IDirect3DVertexBuffer8 *iface)
154 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
155 const struct wined3d_resource *resource;
156 DWORD priority;
158 TRACE("iface %p.\n", iface);
160 wined3d_mutex_lock();
161 resource = wined3d_buffer_get_resource(buffer->wined3d_buffer);
162 priority = wined3d_resource_get_priority(resource);
163 wined3d_mutex_unlock();
165 return priority;
168 static void WINAPI d3d8_vertexbuffer_PreLoad(IDirect3DVertexBuffer8 *iface)
170 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
172 TRACE("iface %p.\n", iface);
174 wined3d_mutex_lock();
175 wined3d_resource_preload(wined3d_buffer_get_resource(buffer->wined3d_buffer));
176 wined3d_mutex_unlock();
179 static D3DRESOURCETYPE WINAPI d3d8_vertexbuffer_GetType(IDirect3DVertexBuffer8 *iface)
181 TRACE("iface %p.\n", iface);
183 return D3DRTYPE_VERTEXBUFFER;
186 static HRESULT WINAPI d3d8_vertexbuffer_Lock(IDirect3DVertexBuffer8 *iface, UINT offset, UINT size,
187 BYTE **data, DWORD flags)
189 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
190 struct wined3d_map_desc wined3d_map_desc;
191 struct wined3d_box wined3d_box = {0};
192 HRESULT hr;
194 TRACE("iface %p, offset %u, size %u, data %p, flags %#x.\n",
195 iface, offset, size, data, flags);
197 wined3d_box.left = offset;
198 wined3d_box.right = offset + size;
199 wined3d_mutex_lock();
200 hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->wined3d_buffer),
201 0, &wined3d_map_desc, &wined3d_box, wined3dmapflags_from_d3dmapflags(flags));
202 wined3d_mutex_unlock();
203 *data = wined3d_map_desc.data;
205 return hr;
208 static HRESULT WINAPI d3d8_vertexbuffer_Unlock(IDirect3DVertexBuffer8 *iface)
210 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
212 TRACE("iface %p.\n", iface);
214 wined3d_mutex_lock();
215 wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->wined3d_buffer), 0);
216 wined3d_mutex_unlock();
218 return D3D_OK;
221 static HRESULT WINAPI d3d8_vertexbuffer_GetDesc(IDirect3DVertexBuffer8 *iface,
222 D3DVERTEXBUFFER_DESC *desc)
224 struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
225 struct wined3d_resource_desc wined3d_desc;
226 struct wined3d_resource *wined3d_resource;
228 TRACE("iface %p, desc %p.\n", iface, desc);
230 wined3d_mutex_lock();
231 wined3d_resource = wined3d_buffer_get_resource(buffer->wined3d_buffer);
232 wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
233 wined3d_mutex_unlock();
235 desc->Format = D3DFMT_VERTEXDATA;
236 desc->Type = D3DRTYPE_VERTEXBUFFER;
237 desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage, wined3d_desc.bind_flags);
238 desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
239 desc->Size = wined3d_desc.size;
240 desc->FVF = buffer->fvf;
242 return D3D_OK;
245 static const IDirect3DVertexBuffer8Vtbl Direct3DVertexBuffer8_Vtbl =
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,
266 static void STDMETHODCALLTYPE d3d8_vertexbuffer_wined3d_object_destroyed(void *parent)
268 struct d3d8_vertexbuffer *buffer = parent;
269 d3d8_resource_cleanup(&buffer->resource);
270 heap_free(buffer);
273 static const struct wined3d_parent_ops d3d8_vertexbuffer_wined3d_parent_ops =
275 d3d8_vertexbuffer_wined3d_object_destroyed,
278 HRESULT vertexbuffer_init(struct d3d8_vertexbuffer *buffer, struct d3d8_device *device,
279 UINT size, DWORD usage, DWORD fvf, D3DPOOL pool)
281 const struct wined3d_parent_ops *parent_ops = &d3d8_null_wined3d_parent_ops;
282 struct wined3d_buffer_desc desc;
283 HRESULT hr;
285 if (pool == D3DPOOL_SCRATCH)
287 WARN("Vertex buffer with D3DPOOL_SCRATCH requested.\n");
288 return D3DERR_INVALIDCALL;
291 /* In d3d8, buffers can't be used as rendertarget or depth/stencil buffer. */
292 if (usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL))
293 return D3DERR_INVALIDCALL;
295 buffer->IDirect3DVertexBuffer8_iface.lpVtbl = &Direct3DVertexBuffer8_Vtbl;
296 d3d8_resource_init(&buffer->resource);
297 buffer->fvf = fvf;
299 desc.byte_width = size;
300 desc.usage = usage & WINED3DUSAGE_MASK;
301 desc.bind_flags = 0;
302 desc.access = wined3daccess_from_d3dpool(pool, usage)
303 | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
304 desc.misc_flags = 0;
305 desc.structure_byte_stride = 0;
307 if (desc.access & WINED3D_RESOURCE_ACCESS_GPU)
309 desc.bind_flags = WINED3D_BIND_VERTEX_BUFFER;
310 parent_ops = &d3d8_vertexbuffer_wined3d_parent_ops;
313 wined3d_mutex_lock();
314 hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer, parent_ops, &buffer->wined3d_buffer);
315 if (SUCCEEDED(hr) && !(desc.access & WINED3D_RESOURCE_ACCESS_GPU))
317 desc.bind_flags = WINED3D_BIND_VERTEX_BUFFER;
318 desc.access = WINED3D_RESOURCE_ACCESS_GPU;
319 if (FAILED(hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer,
320 &d3d8_vertexbuffer_wined3d_parent_ops, &buffer->draw_buffer)))
321 wined3d_buffer_decref(buffer->wined3d_buffer);
323 wined3d_mutex_unlock();
324 if (FAILED(hr))
326 WARN("Failed to create wined3d buffer, hr %#x.\n", hr);
327 return hr;
330 buffer->parent_device = &device->IDirect3DDevice8_iface;
331 IDirect3DDevice8_AddRef(buffer->parent_device);
333 return D3D_OK;
336 struct d3d8_vertexbuffer *unsafe_impl_from_IDirect3DVertexBuffer8(IDirect3DVertexBuffer8 *iface)
338 if (!iface)
339 return NULL;
340 assert(iface->lpVtbl == &Direct3DVertexBuffer8_Vtbl);
342 return impl_from_IDirect3DVertexBuffer8(iface);
345 static inline struct d3d8_indexbuffer *impl_from_IDirect3DIndexBuffer8(IDirect3DIndexBuffer8 *iface)
347 return CONTAINING_RECORD(iface, struct d3d8_indexbuffer, IDirect3DIndexBuffer8_iface);
350 static HRESULT WINAPI d3d8_indexbuffer_QueryInterface(IDirect3DIndexBuffer8 *iface, REFIID riid, void **object)
352 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
354 if (IsEqualGUID(riid, &IID_IDirect3DIndexBuffer8)
355 || IsEqualGUID(riid, &IID_IDirect3DResource8)
356 || IsEqualGUID(riid, &IID_IUnknown))
358 IDirect3DIndexBuffer8_AddRef(iface);
359 *object = iface;
360 return S_OK;
363 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
365 *object = NULL;
366 return E_NOINTERFACE;
369 static ULONG WINAPI d3d8_indexbuffer_AddRef(IDirect3DIndexBuffer8 *iface)
371 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
372 ULONG refcount = InterlockedIncrement(&buffer->resource.refcount);
374 TRACE("%p increasing refcount to %u.\n", iface, refcount);
376 if (refcount == 1)
378 IDirect3DDevice8_AddRef(buffer->parent_device);
379 wined3d_mutex_lock();
380 wined3d_buffer_incref(buffer->wined3d_buffer);
381 if (buffer->draw_buffer)
382 wined3d_buffer_incref(buffer->draw_buffer);
383 wined3d_mutex_unlock();
386 return refcount;
389 static ULONG WINAPI d3d8_indexbuffer_Release(IDirect3DIndexBuffer8 *iface)
391 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
392 ULONG refcount = InterlockedDecrement(&buffer->resource.refcount);
394 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
396 if (!refcount)
398 struct wined3d_buffer *draw_buffer = buffer->draw_buffer;
399 IDirect3DDevice8 *device = buffer->parent_device;
401 wined3d_mutex_lock();
402 wined3d_buffer_decref(buffer->wined3d_buffer);
403 if (draw_buffer)
404 wined3d_buffer_decref(draw_buffer);
405 wined3d_mutex_unlock();
407 /* Release the device last, as it may cause the device to be destroyed. */
408 IDirect3DDevice8_Release(device);
411 return refcount;
414 static HRESULT WINAPI d3d8_indexbuffer_GetDevice(IDirect3DIndexBuffer8 *iface,
415 IDirect3DDevice8 **device)
417 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
419 TRACE("iface %p, device %p.\n", iface, device);
421 *device = buffer->parent_device;
422 IDirect3DDevice8_AddRef(*device);
424 TRACE("Returning device %p.\n", *device);
426 return D3D_OK;
429 static HRESULT WINAPI d3d8_indexbuffer_SetPrivateData(IDirect3DIndexBuffer8 *iface,
430 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
432 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
433 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
434 iface, debugstr_guid(guid), data, data_size, flags);
436 return d3d8_resource_set_private_data(&buffer->resource, guid, data, data_size, flags);
439 static HRESULT WINAPI d3d8_indexbuffer_GetPrivateData(IDirect3DIndexBuffer8 *iface,
440 REFGUID guid, void *data, DWORD *data_size)
442 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
443 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
444 iface, debugstr_guid(guid), data, data_size);
446 return d3d8_resource_get_private_data(&buffer->resource, guid, data, data_size);
449 static HRESULT WINAPI d3d8_indexbuffer_FreePrivateData(IDirect3DIndexBuffer8 *iface, REFGUID guid)
451 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
452 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
454 return d3d8_resource_free_private_data(&buffer->resource, guid);
457 static DWORD WINAPI d3d8_indexbuffer_SetPriority(IDirect3DIndexBuffer8 *iface, DWORD priority)
459 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
460 struct wined3d_resource *resource;
461 DWORD previous;
463 TRACE("iface %p, priority %u.\n", iface, priority);
465 wined3d_mutex_lock();
466 resource = wined3d_buffer_get_resource(buffer->wined3d_buffer);
467 previous = wined3d_resource_set_priority(resource, priority);
468 wined3d_mutex_unlock();
470 return previous;
473 static DWORD WINAPI d3d8_indexbuffer_GetPriority(IDirect3DIndexBuffer8 *iface)
475 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
476 const struct wined3d_resource *resource;
477 DWORD priority;
479 TRACE("iface %p.\n", iface);
481 wined3d_mutex_lock();
482 resource = wined3d_buffer_get_resource(buffer->wined3d_buffer);
483 priority = wined3d_resource_get_priority(resource);
484 wined3d_mutex_unlock();
486 return priority;
489 static void WINAPI d3d8_indexbuffer_PreLoad(IDirect3DIndexBuffer8 *iface)
491 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
493 TRACE("iface %p.\n", iface);
495 wined3d_mutex_lock();
496 wined3d_resource_preload(wined3d_buffer_get_resource(buffer->wined3d_buffer));
497 wined3d_mutex_unlock();
500 static D3DRESOURCETYPE WINAPI d3d8_indexbuffer_GetType(IDirect3DIndexBuffer8 *iface)
502 TRACE("iface %p.\n", iface);
504 return D3DRTYPE_INDEXBUFFER;
507 static HRESULT WINAPI d3d8_indexbuffer_Lock(IDirect3DIndexBuffer8 *iface, UINT offset, UINT size,
508 BYTE **data, DWORD flags)
510 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
511 struct wined3d_map_desc wined3d_map_desc;
512 struct wined3d_box wined3d_box = {0};
513 HRESULT hr;
515 TRACE("iface %p, offset %u, size %u, data %p, flags %#x.\n",
516 iface, offset, size, data, flags);
518 wined3d_box.left = offset;
519 wined3d_box.right = offset + size;
520 wined3d_mutex_lock();
521 hr = wined3d_resource_map(wined3d_buffer_get_resource(buffer->wined3d_buffer),
522 0, &wined3d_map_desc, &wined3d_box, wined3dmapflags_from_d3dmapflags(flags));
523 wined3d_mutex_unlock();
524 *data = wined3d_map_desc.data;
526 return hr;
529 static HRESULT WINAPI d3d8_indexbuffer_Unlock(IDirect3DIndexBuffer8 *iface)
531 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
533 TRACE("iface %p.\n", iface);
535 wined3d_mutex_lock();
536 wined3d_resource_unmap(wined3d_buffer_get_resource(buffer->wined3d_buffer), 0);
537 wined3d_mutex_unlock();
539 return D3D_OK;
542 static HRESULT WINAPI d3d8_indexbuffer_GetDesc(IDirect3DIndexBuffer8 *iface,
543 D3DINDEXBUFFER_DESC *desc)
545 struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
546 struct wined3d_resource_desc wined3d_desc;
547 struct wined3d_resource *wined3d_resource;
549 TRACE("iface %p, desc %p.\n", iface, desc);
551 wined3d_mutex_lock();
552 wined3d_resource = wined3d_buffer_get_resource(buffer->wined3d_buffer);
553 wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
554 wined3d_mutex_unlock();
556 desc->Format = d3dformat_from_wined3dformat(buffer->format);
557 desc->Type = D3DRTYPE_INDEXBUFFER;
558 desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage, wined3d_desc.bind_flags);
559 desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
560 desc->Size = wined3d_desc.size;
562 return D3D_OK;
565 static const IDirect3DIndexBuffer8Vtbl d3d8_indexbuffer_vtbl =
567 /* IUnknown */
568 d3d8_indexbuffer_QueryInterface,
569 d3d8_indexbuffer_AddRef,
570 d3d8_indexbuffer_Release,
571 /* IDirect3DResource8 */
572 d3d8_indexbuffer_GetDevice,
573 d3d8_indexbuffer_SetPrivateData,
574 d3d8_indexbuffer_GetPrivateData,
575 d3d8_indexbuffer_FreePrivateData,
576 d3d8_indexbuffer_SetPriority,
577 d3d8_indexbuffer_GetPriority,
578 d3d8_indexbuffer_PreLoad,
579 d3d8_indexbuffer_GetType,
580 /* IDirect3DIndexBuffer8 */
581 d3d8_indexbuffer_Lock,
582 d3d8_indexbuffer_Unlock,
583 d3d8_indexbuffer_GetDesc,
586 static void STDMETHODCALLTYPE d3d8_indexbuffer_wined3d_object_destroyed(void *parent)
588 struct d3d8_indexbuffer *buffer = parent;
589 d3d8_resource_cleanup(&buffer->resource);
590 heap_free(buffer);
593 static const struct wined3d_parent_ops d3d8_indexbuffer_wined3d_parent_ops =
595 d3d8_indexbuffer_wined3d_object_destroyed,
598 HRESULT indexbuffer_init(struct d3d8_indexbuffer *buffer, struct d3d8_device *device,
599 UINT size, DWORD usage, D3DFORMAT format, D3DPOOL pool)
601 const struct wined3d_parent_ops *parent_ops = &d3d8_null_wined3d_parent_ops;
602 struct wined3d_buffer_desc desc;
603 HRESULT hr;
605 if (pool == D3DPOOL_SCRATCH)
606 return D3DERR_INVALIDCALL;
608 /* In d3d8, buffers can't be used as rendertarget or depth/stencil buffer. */
609 if (usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL))
610 return D3DERR_INVALIDCALL;
612 desc.byte_width = size;
613 desc.usage = (usage & WINED3DUSAGE_MASK) | WINED3DUSAGE_STATICDECL;
614 desc.bind_flags = 0;
615 desc.access = wined3daccess_from_d3dpool(pool, usage)
616 | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
617 desc.misc_flags = 0;
618 desc.structure_byte_stride = 0;
620 if (desc.access & WINED3D_RESOURCE_ACCESS_GPU)
622 desc.bind_flags = WINED3D_BIND_INDEX_BUFFER;
623 parent_ops = &d3d8_indexbuffer_wined3d_parent_ops;
626 buffer->IDirect3DIndexBuffer8_iface.lpVtbl = &d3d8_indexbuffer_vtbl;
627 d3d8_resource_init(&buffer->resource);
628 buffer->format = wined3dformat_from_d3dformat(format);
630 wined3d_mutex_lock();
631 hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer, parent_ops, &buffer->wined3d_buffer);
632 if (SUCCEEDED(hr) && !(desc.access & WINED3D_RESOURCE_ACCESS_GPU))
634 desc.bind_flags = WINED3D_BIND_INDEX_BUFFER;
635 desc.access = WINED3D_RESOURCE_ACCESS_GPU;
636 if (FAILED(hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer,
637 &d3d8_indexbuffer_wined3d_parent_ops, &buffer->draw_buffer)))
638 wined3d_buffer_decref(buffer->wined3d_buffer);
640 wined3d_mutex_unlock();
641 if (FAILED(hr))
643 WARN("Failed to create wined3d buffer, hr %#x.\n", hr);
644 return hr;
647 buffer->parent_device = &device->IDirect3DDevice8_iface;
648 IDirect3DDevice8_AddRef(buffer->parent_device);
650 return D3D_OK;
653 struct d3d8_indexbuffer *unsafe_impl_from_IDirect3DIndexBuffer8(IDirect3DIndexBuffer8 *iface)
655 if (!iface)
656 return NULL;
657 assert(iface->lpVtbl == &d3d8_indexbuffer_vtbl);
659 return impl_from_IDirect3DIndexBuffer8(iface);