blob: 4ab6524c2c02e534b64457fa1f9910fcb51b49a8 [file] [log] [blame]
Henri Verbeetc9c034f2010-09-01 18:41:05 +02001/*
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"
Michael Stefaniucc1eeeec2011-07-05 00:43:50 +020020#include <assert.h>
Henri Verbeetc9c034f2010-09-01 18:41:05 +020021#include "d3d8_private.h"
22
23WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
24
Henri Verbeetdc6581c2011-06-16 22:38:28 +020025static inline IDirect3DVertexBuffer8Impl *impl_from_IDirect3DVertexBuffer8(IDirect3DVertexBuffer8 *iface)
26{
Michael Stefaniuc9ab233e2011-07-08 12:24:46 +020027 return CONTAINING_RECORD(iface, IDirect3DVertexBuffer8Impl, IDirect3DVertexBuffer8_iface);
Henri Verbeetdc6581c2011-06-16 22:38:28 +020028}
29
Henri Verbeetc9c034f2010-09-01 18:41:05 +020030static 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
49static ULONG WINAPI d3d8_vertexbuffer_AddRef(IDirect3DVertexBuffer8 *iface)
50{
Michael Stefaniuc9ab233e2011-07-08 12:24:46 +020051 IDirect3DVertexBuffer8Impl *buffer = impl_from_IDirect3DVertexBuffer8(iface);
Henri Verbeetc9c034f2010-09-01 18:41:05 +020052 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();
Henri Verbeeta27ee752011-03-03 21:49:09 +010060 wined3d_buffer_incref(buffer->wineD3DVertexBuffer);
Henri Verbeetc9c034f2010-09-01 18:41:05 +020061 wined3d_mutex_unlock();
62 }
63
64 return refcount;
65}
66
67static ULONG WINAPI d3d8_vertexbuffer_Release(IDirect3DVertexBuffer8 *iface)
68{
Michael Stefaniuc9ab233e2011-07-08 12:24:46 +020069 IDirect3DVertexBuffer8Impl *buffer = impl_from_IDirect3DVertexBuffer8(iface);
Henri Verbeetc9c034f2010-09-01 18:41:05 +020070 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();
Henri Verbeeta27ee752011-03-03 21:49:09 +010079 wined3d_buffer_decref(buffer->wineD3DVertexBuffer);
Henri Verbeetc9c034f2010-09-01 18:41:05 +020080 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
Michael Stefaniuc9ab233e2011-07-08 12:24:46 +020089static HRESULT WINAPI d3d8_vertexbuffer_GetDevice(IDirect3DVertexBuffer8 *iface,
90 IDirect3DDevice8 **device)
Henri Verbeetc9c034f2010-09-01 18:41:05 +020091{
Michael Stefaniuc9ab233e2011-07-08 12:24:46 +020092 IDirect3DVertexBuffer8Impl *buffer = impl_from_IDirect3DVertexBuffer8(iface);
93
Henri Verbeetc9c034f2010-09-01 18:41:05 +020094 TRACE("iface %p, device %p.\n", iface, device);
95
Michael Stefaniuc9ab233e2011-07-08 12:24:46 +020096 *device = buffer->parentDevice;
Henri Verbeetc9c034f2010-09-01 18:41:05 +020097 IDirect3DDevice8_AddRef(*device);
98
99 TRACE("Returning device %p.\n", *device);
100
101 return D3D_OK;
102}
103
104static HRESULT WINAPI d3d8_vertexbuffer_SetPrivateData(IDirect3DVertexBuffer8 *iface,
105 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
106{
Henri Verbeetdc6581c2011-06-16 22:38:28 +0200107 IDirect3DVertexBuffer8Impl *buffer = impl_from_IDirect3DVertexBuffer8(iface);
108 struct wined3d_resource *resource;
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200109 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();
Henri Verbeetdc6581c2011-06-16 22:38:28 +0200115 resource = wined3d_buffer_get_resource(buffer->wineD3DVertexBuffer);
116 hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200117 wined3d_mutex_unlock();
118
119 return hr;
120}
121
122static HRESULT WINAPI d3d8_vertexbuffer_GetPrivateData(IDirect3DVertexBuffer8 *iface,
123 REFGUID guid, void *data, DWORD *data_size)
124{
Henri Verbeetdc6581c2011-06-16 22:38:28 +0200125 IDirect3DVertexBuffer8Impl *buffer = impl_from_IDirect3DVertexBuffer8(iface);
126 struct wined3d_resource *resource;
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200127 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();
Henri Verbeetdc6581c2011-06-16 22:38:28 +0200133 resource = wined3d_buffer_get_resource(buffer->wineD3DVertexBuffer);
134 hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200135 wined3d_mutex_unlock();
136
137 return hr;
138}
139
140static HRESULT WINAPI d3d8_vertexbuffer_FreePrivateData(IDirect3DVertexBuffer8 *iface, REFGUID guid)
141{
Henri Verbeetdc6581c2011-06-16 22:38:28 +0200142 IDirect3DVertexBuffer8Impl *buffer = impl_from_IDirect3DVertexBuffer8(iface);
143 struct wined3d_resource *resource;
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200144 HRESULT hr;
145
146 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
147
148 wined3d_mutex_lock();
Henri Verbeetdc6581c2011-06-16 22:38:28 +0200149 resource = wined3d_buffer_get_resource(buffer->wineD3DVertexBuffer);
150 hr = wined3d_resource_free_private_data(resource, guid);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200151 wined3d_mutex_unlock();
152
153 return hr;
154}
155
156static DWORD WINAPI d3d8_vertexbuffer_SetPriority(IDirect3DVertexBuffer8 *iface, DWORD priority)
157{
Michael Stefaniuc9ab233e2011-07-08 12:24:46 +0200158 IDirect3DVertexBuffer8Impl *buffer = impl_from_IDirect3DVertexBuffer8(iface);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200159 DWORD previous;
160
161 TRACE("iface %p, priority %u.\n", iface, priority);
162
163 wined3d_mutex_lock();
Michael Stefaniuc9ab233e2011-07-08 12:24:46 +0200164 previous = wined3d_buffer_set_priority(buffer->wineD3DVertexBuffer, priority);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200165 wined3d_mutex_unlock();
166
167 return previous;
168}
169
170static DWORD WINAPI d3d8_vertexbuffer_GetPriority(IDirect3DVertexBuffer8 *iface)
171{
Michael Stefaniuc9ab233e2011-07-08 12:24:46 +0200172 IDirect3DVertexBuffer8Impl *buffer = impl_from_IDirect3DVertexBuffer8(iface);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200173 DWORD priority;
174
175 TRACE("iface %p.\n", iface);
176
177 wined3d_mutex_lock();
Michael Stefaniuc9ab233e2011-07-08 12:24:46 +0200178 priority = wined3d_buffer_get_priority(buffer->wineD3DVertexBuffer);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200179 wined3d_mutex_unlock();
180
181 return priority;
182}
183
184static void WINAPI d3d8_vertexbuffer_PreLoad(IDirect3DVertexBuffer8 *iface)
185{
Michael Stefaniuc9ab233e2011-07-08 12:24:46 +0200186 IDirect3DVertexBuffer8Impl *buffer = impl_from_IDirect3DVertexBuffer8(iface);
187
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200188 TRACE("iface %p.\n", iface);
189
190 wined3d_mutex_lock();
Michael Stefaniuc9ab233e2011-07-08 12:24:46 +0200191 wined3d_buffer_preload(buffer->wineD3DVertexBuffer);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200192 wined3d_mutex_unlock();
193}
194
195static D3DRESOURCETYPE WINAPI d3d8_vertexbuffer_GetType(IDirect3DVertexBuffer8 *iface)
196{
197 TRACE("iface %p.\n", iface);
198
199 return D3DRTYPE_VERTEXBUFFER;
200}
201
Michael Stefaniuc9ab233e2011-07-08 12:24:46 +0200202static HRESULT WINAPI d3d8_vertexbuffer_Lock(IDirect3DVertexBuffer8 *iface, UINT offset, UINT size,
203 BYTE **data, DWORD flags)
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200204{
Michael Stefaniuc9ab233e2011-07-08 12:24:46 +0200205 IDirect3DVertexBuffer8Impl *buffer = impl_from_IDirect3DVertexBuffer8(iface);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200206 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();
Michael Stefaniuc9ab233e2011-07-08 12:24:46 +0200212 hr = wined3d_buffer_map(buffer->wineD3DVertexBuffer, offset, size, data, flags);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200213 wined3d_mutex_unlock();
214
215 return hr;
216}
217
218static HRESULT WINAPI d3d8_vertexbuffer_Unlock(IDirect3DVertexBuffer8 *iface)
219{
Michael Stefaniuc9ab233e2011-07-08 12:24:46 +0200220 IDirect3DVertexBuffer8Impl *buffer = impl_from_IDirect3DVertexBuffer8(iface);
221
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200222 TRACE("iface %p.\n", iface);
223
224 wined3d_mutex_lock();
Michael Stefaniuc9ab233e2011-07-08 12:24:46 +0200225 wined3d_buffer_unmap(buffer->wineD3DVertexBuffer);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200226 wined3d_mutex_unlock();
227
Henri Verbeet70f4e662010-10-15 14:35:12 +0200228 return D3D_OK;
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200229}
230
Michael Stefaniuc9ab233e2011-07-08 12:24:46 +0200231static HRESULT WINAPI d3d8_vertexbuffer_GetDesc(IDirect3DVertexBuffer8 *iface,
232 D3DVERTEXBUFFER_DESC *desc)
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200233{
Michael Stefaniuc9ab233e2011-07-08 12:24:46 +0200234 IDirect3DVertexBuffer8Impl *buffer = impl_from_IDirect3DVertexBuffer8(iface);
Henri Verbeet756fdb72011-03-08 19:41:05 +0100235 struct wined3d_resource_desc wined3d_desc;
Henri Verbeetadb1e102011-03-10 19:07:10 +0100236 struct wined3d_resource *wined3d_resource;
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200237
238 TRACE("iface %p, desc %p.\n", iface, desc);
239
240 wined3d_mutex_lock();
Henri Verbeetadb1e102011-03-10 19:07:10 +0100241 wined3d_resource = wined3d_buffer_get_resource(buffer->wineD3DVertexBuffer);
242 wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200243 wined3d_mutex_unlock();
244
Henri Verbeetfd7c1cb2010-09-14 13:38:38 +0200245 desc->Type = D3DRTYPE_VERTEXBUFFER;
Henri Verbeetef9be112012-01-10 20:36:59 +0100246 desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
Henri Verbeet756fdb72011-03-08 19:41:05 +0100247 desc->Pool = wined3d_desc.pool;
248 desc->Size = wined3d_desc.size;
Henri Verbeetfd7c1cb2010-09-14 13:38:38 +0200249 desc->FVF = buffer->fvf;
250 desc->Format = D3DFMT_VERTEXDATA;
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200251
Henri Verbeetfd7c1cb2010-09-14 13:38:38 +0200252 return D3D_OK;
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200253}
254
255static 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
276static void STDMETHODCALLTYPE d3d8_vertexbuffer_wined3d_object_destroyed(void *parent)
277{
278 HeapFree(GetProcessHeap(), 0, parent);
279}
280
281static const struct wined3d_parent_ops d3d8_vertexbuffer_wined3d_parent_ops =
282{
283 d3d8_vertexbuffer_wined3d_object_destroyed,
284};
285
286HRESULT vertexbuffer_init(IDirect3DVertexBuffer8Impl *buffer, IDirect3DDevice8Impl *device,
287 UINT size, DWORD usage, DWORD fvf, D3DPOOL pool)
288{
289 HRESULT hr;
290
Michael Stefaniuc9ab233e2011-07-08 12:24:46 +0200291 buffer->IDirect3DVertexBuffer8_iface.lpVtbl = &Direct3DVertexBuffer8_Vtbl;
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200292 buffer->ref = 1;
293 buffer->fvf = fvf;
294
295 wined3d_mutex_lock();
Henri Verbeet8d4ca1f2011-05-16 23:01:22 +0200296 hr = wined3d_buffer_create_vb(device->wined3d_device, size, usage & WINED3DUSAGE_MASK,
Henri Verbeete53a2772012-01-17 21:13:37 +0100297 (enum wined3d_pool)pool, buffer, &d3d8_vertexbuffer_wined3d_parent_ops, &buffer->wineD3DVertexBuffer);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200298 wined3d_mutex_unlock();
299 if (FAILED(hr))
300 {
301 WARN("Failed to create wined3d buffer, hr %#x.\n", hr);
302 return hr;
303 }
304
Michael Stefaniuc54a61ae2011-01-28 01:17:54 +0100305 buffer->parentDevice = &device->IDirect3DDevice8_iface;
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200306 IUnknown_AddRef(buffer->parentDevice);
307
308 return D3D_OK;
309}
310
Michael Stefaniucaa8e4dd2011-07-08 12:22:14 +0200311IDirect3DVertexBuffer8Impl *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
Henri Verbeet37d70102011-06-16 22:38:29 +0200320static inline IDirect3DIndexBuffer8Impl *impl_from_IDirect3DIndexBuffer8(IDirect3DIndexBuffer8 *iface)
321{
Michael Stefaniuc638cf802011-07-05 00:46:30 +0200322 return CONTAINING_RECORD(iface, IDirect3DIndexBuffer8Impl, IDirect3DIndexBuffer8_iface);
Henri Verbeet37d70102011-06-16 22:38:29 +0200323}
324
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200325static 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
344static ULONG WINAPI d3d8_indexbuffer_AddRef(IDirect3DIndexBuffer8 *iface)
345{
Michael Stefaniuc638cf802011-07-05 00:46:30 +0200346 IDirect3DIndexBuffer8Impl *buffer = impl_from_IDirect3DIndexBuffer8(iface);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200347 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();
Henri Verbeeta27ee752011-03-03 21:49:09 +0100355 wined3d_buffer_incref(buffer->wineD3DIndexBuffer);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200356 wined3d_mutex_unlock();
357 }
358
359 return refcount;
360}
361
362static ULONG WINAPI d3d8_indexbuffer_Release(IDirect3DIndexBuffer8 *iface)
363{
Michael Stefaniuc638cf802011-07-05 00:46:30 +0200364 IDirect3DIndexBuffer8Impl *buffer = impl_from_IDirect3DIndexBuffer8(iface);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200365 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();
Henri Verbeeta27ee752011-03-03 21:49:09 +0100374 wined3d_buffer_decref(buffer->wineD3DIndexBuffer);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200375 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
Michael Stefaniuc638cf802011-07-05 00:46:30 +0200384static HRESULT WINAPI d3d8_indexbuffer_GetDevice(IDirect3DIndexBuffer8 *iface,
385 IDirect3DDevice8 **device)
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200386{
Michael Stefaniuc638cf802011-07-05 00:46:30 +0200387 IDirect3DIndexBuffer8Impl *buffer = impl_from_IDirect3DIndexBuffer8(iface);
388
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200389 TRACE("iface %p, device %p.\n", iface, device);
390
Michael Stefaniuc638cf802011-07-05 00:46:30 +0200391 *device = buffer->parentDevice;
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200392 IDirect3DDevice8_AddRef(*device);
393
394 TRACE("Returning device %p.\n", *device);
395
396 return D3D_OK;
397}
398
399static HRESULT WINAPI d3d8_indexbuffer_SetPrivateData(IDirect3DIndexBuffer8 *iface,
400 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
401{
Henri Verbeet37d70102011-06-16 22:38:29 +0200402 IDirect3DIndexBuffer8Impl *buffer = impl_from_IDirect3DIndexBuffer8(iface);
403 struct wined3d_resource *resource;
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200404 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();
Henri Verbeet37d70102011-06-16 22:38:29 +0200410 resource = wined3d_buffer_get_resource(buffer->wineD3DIndexBuffer);
411 hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200412 wined3d_mutex_unlock();
413
414 return hr;
415}
416
417static HRESULT WINAPI d3d8_indexbuffer_GetPrivateData(IDirect3DIndexBuffer8 *iface,
418 REFGUID guid, void *data, DWORD *data_size)
419{
Henri Verbeet37d70102011-06-16 22:38:29 +0200420 IDirect3DIndexBuffer8Impl *buffer = impl_from_IDirect3DIndexBuffer8(iface);
421 struct wined3d_resource *resource;
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200422 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();
Henri Verbeet37d70102011-06-16 22:38:29 +0200428 resource = wined3d_buffer_get_resource(buffer->wineD3DIndexBuffer);
429 hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200430 wined3d_mutex_unlock();
431
432 return hr;
433}
434
435static HRESULT WINAPI d3d8_indexbuffer_FreePrivateData(IDirect3DIndexBuffer8 *iface, REFGUID guid)
436{
Henri Verbeet37d70102011-06-16 22:38:29 +0200437 IDirect3DIndexBuffer8Impl *buffer = impl_from_IDirect3DIndexBuffer8(iface);
438 struct wined3d_resource *resource;
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200439 HRESULT hr;
440
441 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
442
443 wined3d_mutex_lock();
Henri Verbeet37d70102011-06-16 22:38:29 +0200444 resource = wined3d_buffer_get_resource(buffer->wineD3DIndexBuffer);
445 hr = wined3d_resource_free_private_data(resource, guid);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200446 wined3d_mutex_unlock();
447
448 return hr;
449}
450
451static DWORD WINAPI d3d8_indexbuffer_SetPriority(IDirect3DIndexBuffer8 *iface, DWORD priority)
452{
Michael Stefaniuc638cf802011-07-05 00:46:30 +0200453 IDirect3DIndexBuffer8Impl *buffer = impl_from_IDirect3DIndexBuffer8(iface);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200454 DWORD previous;
455
456 TRACE("iface %p, priority %u.\n", iface, priority);
457
458 wined3d_mutex_lock();
Michael Stefaniuc638cf802011-07-05 00:46:30 +0200459 previous = wined3d_buffer_set_priority(buffer->wineD3DIndexBuffer, priority);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200460 wined3d_mutex_unlock();
461
462 return previous;
463}
464
465static DWORD WINAPI d3d8_indexbuffer_GetPriority(IDirect3DIndexBuffer8 *iface)
466{
Michael Stefaniuc638cf802011-07-05 00:46:30 +0200467 IDirect3DIndexBuffer8Impl *buffer = impl_from_IDirect3DIndexBuffer8(iface);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200468 DWORD priority;
469
470 TRACE("iface %p.\n", iface);
471
472 wined3d_mutex_lock();
Michael Stefaniuc638cf802011-07-05 00:46:30 +0200473 priority = wined3d_buffer_get_priority(buffer->wineD3DIndexBuffer);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200474 wined3d_mutex_unlock();
475
476 return priority;
477}
478
479static void WINAPI d3d8_indexbuffer_PreLoad(IDirect3DIndexBuffer8 *iface)
480{
Michael Stefaniuc638cf802011-07-05 00:46:30 +0200481 IDirect3DIndexBuffer8Impl *buffer = impl_from_IDirect3DIndexBuffer8(iface);
482
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200483 TRACE("iface %p.\n", iface);
484
485 wined3d_mutex_lock();
Michael Stefaniuc638cf802011-07-05 00:46:30 +0200486 wined3d_buffer_preload(buffer->wineD3DIndexBuffer);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200487 wined3d_mutex_unlock();
488}
489
490static D3DRESOURCETYPE WINAPI d3d8_indexbuffer_GetType(IDirect3DIndexBuffer8 *iface)
491{
492 TRACE("iface %p.\n", iface);
493
494 return D3DRTYPE_INDEXBUFFER;
495}
496
Michael Stefaniuc638cf802011-07-05 00:46:30 +0200497static HRESULT WINAPI d3d8_indexbuffer_Lock(IDirect3DIndexBuffer8 *iface, UINT offset, UINT size,
498 BYTE **data, DWORD flags)
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200499{
Michael Stefaniuc638cf802011-07-05 00:46:30 +0200500 IDirect3DIndexBuffer8Impl *buffer = impl_from_IDirect3DIndexBuffer8(iface);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200501 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();
Michael Stefaniuc638cf802011-07-05 00:46:30 +0200507 hr = wined3d_buffer_map(buffer->wineD3DIndexBuffer, offset, size, data, flags);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200508 wined3d_mutex_unlock();
509
510 return hr;
511}
512
513static HRESULT WINAPI d3d8_indexbuffer_Unlock(IDirect3DIndexBuffer8 *iface)
514{
Michael Stefaniuc638cf802011-07-05 00:46:30 +0200515 IDirect3DIndexBuffer8Impl *buffer = impl_from_IDirect3DIndexBuffer8(iface);
516
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200517 TRACE("iface %p.\n", iface);
518
519 wined3d_mutex_lock();
Michael Stefaniuc638cf802011-07-05 00:46:30 +0200520 wined3d_buffer_unmap(buffer->wineD3DIndexBuffer);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200521 wined3d_mutex_unlock();
522
Henri Verbeet70f4e662010-10-15 14:35:12 +0200523 return D3D_OK;
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200524}
525
Michael Stefaniuc638cf802011-07-05 00:46:30 +0200526static HRESULT WINAPI d3d8_indexbuffer_GetDesc(IDirect3DIndexBuffer8 *iface,
527 D3DINDEXBUFFER_DESC *desc)
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200528{
Michael Stefaniuc638cf802011-07-05 00:46:30 +0200529 IDirect3DIndexBuffer8Impl *buffer = impl_from_IDirect3DIndexBuffer8(iface);
Henri Verbeet756fdb72011-03-08 19:41:05 +0100530 struct wined3d_resource_desc wined3d_desc;
Henri Verbeetadb1e102011-03-10 19:07:10 +0100531 struct wined3d_resource *wined3d_resource;
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200532
533 TRACE("iface %p, desc %p.\n", iface, desc);
534
535 wined3d_mutex_lock();
Henri Verbeetadb1e102011-03-10 19:07:10 +0100536 wined3d_resource = wined3d_buffer_get_resource(buffer->wineD3DIndexBuffer);
537 wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200538 wined3d_mutex_unlock();
539
Henri Verbeetfd7c1cb2010-09-14 13:38:38 +0200540 desc->Format = d3dformat_from_wined3dformat(buffer->format);
541 desc->Type = D3DRTYPE_INDEXBUFFER;
Henri Verbeetef9be112012-01-10 20:36:59 +0100542 desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
Henri Verbeet756fdb72011-03-08 19:41:05 +0100543 desc->Pool = wined3d_desc.pool;
544 desc->Size = wined3d_desc.size;
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200545
Henri Verbeetfd7c1cb2010-09-14 13:38:38 +0200546 return D3D_OK;
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200547}
548
549static 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
570static void STDMETHODCALLTYPE d3d8_indexbuffer_wined3d_object_destroyed(void *parent)
571{
572 HeapFree(GetProcessHeap(), 0, parent);
573}
574
575static const struct wined3d_parent_ops d3d8_indexbuffer_wined3d_parent_ops =
576{
577 d3d8_indexbuffer_wined3d_object_destroyed,
578};
579
580HRESULT indexbuffer_init(IDirect3DIndexBuffer8Impl *buffer, IDirect3DDevice8Impl *device,
581 UINT size, DWORD usage, D3DFORMAT format, D3DPOOL pool)
582{
583 HRESULT hr;
584
Michael Stefaniuc638cf802011-07-05 00:46:30 +0200585 buffer->IDirect3DIndexBuffer8_iface.lpVtbl = &d3d8_indexbuffer_vtbl;
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200586 buffer->ref = 1;
587 buffer->format = wined3dformat_from_d3dformat(format);
588
589 wined3d_mutex_lock();
Henri Verbeet8d4ca1f2011-05-16 23:01:22 +0200590 hr = wined3d_buffer_create_ib(device->wined3d_device, size, usage & WINED3DUSAGE_MASK,
Henri Verbeete53a2772012-01-17 21:13:37 +0100591 (enum wined3d_pool)pool, buffer, &d3d8_indexbuffer_wined3d_parent_ops, &buffer->wineD3DIndexBuffer);
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200592 wined3d_mutex_unlock();
593 if (FAILED(hr))
594 {
595 WARN("Failed to create wined3d buffer, hr %#x.\n", hr);
596 return hr;
597 }
598
Michael Stefaniuc54a61ae2011-01-28 01:17:54 +0100599 buffer->parentDevice = &device->IDirect3DDevice8_iface;
Henri Verbeetc9c034f2010-09-01 18:41:05 +0200600 IUnknown_AddRef(buffer->parentDevice);
601
602 return D3D_OK;
603}
Michael Stefaniucc1eeeec2011-07-05 00:43:50 +0200604
605IDirect3DIndexBuffer8Impl *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}