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
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
);
42 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
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
);
57 IDirect3DDevice8_AddRef(buffer
->parent_device
);
59 wined3d_buffer_incref(buffer
->wined3d_buffer
);
60 if (buffer
->draw_buffer
)
61 wined3d_buffer_incref(buffer
->draw_buffer
);
62 wined3d_mutex_unlock();
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
);
77 struct wined3d_buffer
*draw_buffer
= buffer
->draw_buffer
;
78 IDirect3DDevice8
*device
= buffer
->parent_device
;
81 wined3d_buffer_decref(buffer
->wined3d_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
);
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
);
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
;
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();
152 static DWORD WINAPI
d3d8_vertexbuffer_GetPriority(IDirect3DVertexBuffer8
*iface
)
154 struct d3d8_vertexbuffer
*buffer
= impl_from_IDirect3DVertexBuffer8(iface
);
155 const struct wined3d_resource
*resource
;
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();
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};
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
;
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();
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
;
245 static const IDirect3DVertexBuffer8Vtbl Direct3DVertexBuffer8_Vtbl
=
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
);
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
;
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
);
299 desc
.byte_width
= size
;
300 desc
.usage
= usage
& WINED3DUSAGE_MASK
;
302 desc
.access
= wined3daccess_from_d3dpool(pool
, usage
)
303 | WINED3D_RESOURCE_ACCESS_MAP_R
| WINED3D_RESOURCE_ACCESS_MAP_W
;
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();
326 WARN("Failed to create wined3d buffer, hr %#x.\n", hr
);
330 buffer
->parent_device
= &device
->IDirect3DDevice8_iface
;
331 IDirect3DDevice8_AddRef(buffer
->parent_device
);
336 struct d3d8_vertexbuffer
*unsafe_impl_from_IDirect3DVertexBuffer8(IDirect3DVertexBuffer8
*iface
)
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
);
363 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
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
);
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();
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
);
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
);
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
);
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
);
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
;
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();
473 static DWORD WINAPI
d3d8_indexbuffer_GetPriority(IDirect3DIndexBuffer8
*iface
)
475 struct d3d8_indexbuffer
*buffer
= impl_from_IDirect3DIndexBuffer8(iface
);
476 const struct wined3d_resource
*resource
;
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();
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};
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
;
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();
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
;
565 static const IDirect3DIndexBuffer8Vtbl d3d8_indexbuffer_vtbl
=
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
);
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
;
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
;
615 desc
.access
= wined3daccess_from_d3dpool(pool
, usage
)
616 | WINED3D_RESOURCE_ACCESS_MAP_R
| WINED3D_RESOURCE_ACCESS_MAP_W
;
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();
643 WARN("Failed to create wined3d buffer, hr %#x.\n", hr
);
647 buffer
->parent_device
= &device
->IDirect3DDevice8_iface
;
648 IDirect3DDevice8_AddRef(buffer
->parent_device
);
653 struct d3d8_indexbuffer
*unsafe_impl_from_IDirect3DIndexBuffer8(IDirect3DIndexBuffer8
*iface
)
657 assert(iface
->lpVtbl
== &d3d8_indexbuffer_vtbl
);
659 return impl_from_IDirect3DIndexBuffer8(iface
);