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