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_texture *impl_from_IDirect3DTexture8(IDirect3DTexture8 *iface) 25 { 26 return CONTAINING_RECORD((IDirect3DBaseTexture8 *)iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); 27 } 28 29 static inline struct d3d8_texture *impl_from_IDirect3DCubeTexture8(IDirect3DCubeTexture8 *iface) 30 { 31 return CONTAINING_RECORD((IDirect3DBaseTexture8 *)iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); 32 } 33 34 static inline struct d3d8_texture *impl_from_IDirect3DVolumeTexture8(IDirect3DVolumeTexture8 *iface) 35 { 36 return CONTAINING_RECORD((IDirect3DBaseTexture8 *)iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); 37 } 38 39 static HRESULT WINAPI d3d8_texture_2d_QueryInterface(IDirect3DTexture8 *iface, REFIID riid, void **out) 40 { 41 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); 42 43 if (IsEqualGUID(riid, &IID_IDirect3DTexture8) 44 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture8) 45 || IsEqualGUID(riid, &IID_IDirect3DResource8) 46 || IsEqualGUID(riid, &IID_IUnknown)) 47 { 48 IDirect3DTexture8_AddRef(iface); 49 *out = iface; 50 return S_OK; 51 } 52 53 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); 54 55 *out = NULL; 56 return E_NOINTERFACE; 57 } 58 59 static ULONG WINAPI d3d8_texture_2d_AddRef(IDirect3DTexture8 *iface) 60 { 61 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface); 62 ULONG ref = InterlockedIncrement(&texture->resource.refcount); 63 64 TRACE("%p increasing refcount to %u.\n", iface, ref); 65 66 if (ref == 1) 67 { 68 struct d3d8_surface *surface; 69 70 IDirect3DDevice8_AddRef(texture->parent_device); 71 wined3d_mutex_lock(); 72 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d8_surface, rtv_entry) 73 { 74 wined3d_rendertarget_view_incref(surface->wined3d_rtv); 75 } 76 wined3d_texture_incref(texture->wined3d_texture); 77 wined3d_mutex_unlock(); 78 } 79 80 return ref; 81 } 82 83 static ULONG WINAPI d3d8_texture_2d_Release(IDirect3DTexture8 *iface) 84 { 85 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface); 86 ULONG ref = InterlockedDecrement(&texture->resource.refcount); 87 88 TRACE("%p decreasing refcount to %u.\n", iface, ref); 89 90 if (!ref) 91 { 92 IDirect3DDevice8 *parent_device = texture->parent_device; 93 struct d3d8_surface *surface; 94 95 wined3d_mutex_lock(); 96 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d8_surface, rtv_entry) 97 { 98 wined3d_rendertarget_view_decref(surface->wined3d_rtv); 99 } 100 wined3d_texture_decref(texture->wined3d_texture); 101 wined3d_mutex_unlock(); 102 103 /* Release the device last, as it may cause the device to be destroyed. */ 104 IDirect3DDevice8_Release(parent_device); 105 } 106 return ref; 107 } 108 109 static HRESULT WINAPI d3d8_texture_2d_GetDevice(IDirect3DTexture8 *iface, IDirect3DDevice8 **device) 110 { 111 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface); 112 113 TRACE("iface %p, device %p.\n", iface, device); 114 115 *device = texture->parent_device; 116 IDirect3DDevice8_AddRef(*device); 117 118 TRACE("Returning device %p.\n", *device); 119 120 return D3D_OK; 121 } 122 123 static HRESULT WINAPI d3d8_texture_2d_SetPrivateData(IDirect3DTexture8 *iface, 124 REFGUID guid, const void *data, DWORD data_size, DWORD flags) 125 { 126 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface); 127 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n", 128 iface, debugstr_guid(guid), data, data_size, flags); 129 130 return d3d8_resource_set_private_data(&texture->resource, guid, data, data_size, flags); 131 } 132 133 static HRESULT WINAPI d3d8_texture_2d_GetPrivateData(IDirect3DTexture8 *iface, 134 REFGUID guid, void *data, DWORD *data_size) 135 { 136 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface); 137 TRACE("iface %p, guid %s, data %p, data_size %p.\n", 138 iface, debugstr_guid(guid), data, data_size); 139 140 return d3d8_resource_get_private_data(&texture->resource, guid, data, data_size); 141 } 142 143 static HRESULT WINAPI d3d8_texture_2d_FreePrivateData(IDirect3DTexture8 *iface, REFGUID guid) 144 { 145 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface); 146 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid)); 147 148 return d3d8_resource_free_private_data(&texture->resource, guid); 149 } 150 151 static DWORD WINAPI d3d8_texture_2d_SetPriority(IDirect3DTexture8 *iface, DWORD priority) 152 { 153 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface); 154 struct wined3d_resource *resource; 155 DWORD ret; 156 157 TRACE("iface %p, priority %u.\n", iface, priority); 158 159 wined3d_mutex_lock(); 160 resource = wined3d_texture_get_resource(texture->wined3d_texture); 161 ret = wined3d_resource_set_priority(resource, priority); 162 wined3d_mutex_unlock(); 163 164 return ret; 165 } 166 167 static DWORD WINAPI d3d8_texture_2d_GetPriority(IDirect3DTexture8 *iface) 168 { 169 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface); 170 const struct wined3d_resource *resource; 171 DWORD ret; 172 173 TRACE("iface %p.\n", iface); 174 175 wined3d_mutex_lock(); 176 resource = wined3d_texture_get_resource(texture->wined3d_texture); 177 ret = wined3d_resource_get_priority(resource); 178 wined3d_mutex_unlock(); 179 180 return ret; 181 } 182 183 static void WINAPI d3d8_texture_2d_PreLoad(IDirect3DTexture8 *iface) 184 { 185 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface); 186 187 TRACE("iface %p.\n", iface); 188 189 wined3d_mutex_lock(); 190 wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture)); 191 wined3d_mutex_unlock(); 192 } 193 194 static D3DRESOURCETYPE WINAPI d3d8_texture_2d_GetType(IDirect3DTexture8 *iface) 195 { 196 TRACE("iface %p.\n", iface); 197 198 return D3DRTYPE_TEXTURE; 199 } 200 201 static DWORD WINAPI d3d8_texture_2d_SetLOD(IDirect3DTexture8 *iface, DWORD lod) 202 { 203 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface); 204 DWORD ret; 205 206 TRACE("iface %p, lod %u.\n", iface, lod); 207 208 wined3d_mutex_lock(); 209 ret = wined3d_texture_set_lod(texture->wined3d_texture, lod); 210 wined3d_mutex_unlock(); 211 212 return ret; 213 } 214 215 static DWORD WINAPI d3d8_texture_2d_GetLOD(IDirect3DTexture8 *iface) 216 { 217 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface); 218 DWORD ret; 219 220 TRACE("iface %p.\n", iface); 221 222 wined3d_mutex_lock(); 223 ret = wined3d_texture_get_lod(texture->wined3d_texture); 224 wined3d_mutex_unlock(); 225 226 return ret; 227 } 228 229 static DWORD WINAPI d3d8_texture_2d_GetLevelCount(IDirect3DTexture8 *iface) 230 { 231 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface); 232 DWORD ret; 233 234 TRACE("iface %p.\n", iface); 235 236 wined3d_mutex_lock(); 237 ret = wined3d_texture_get_level_count(texture->wined3d_texture); 238 wined3d_mutex_unlock(); 239 240 return ret; 241 } 242 243 static HRESULT WINAPI d3d8_texture_2d_GetLevelDesc(IDirect3DTexture8 *iface, UINT level, D3DSURFACE_DESC *desc) 244 { 245 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface); 246 struct wined3d_sub_resource_desc wined3d_desc; 247 HRESULT hr; 248 249 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc); 250 251 wined3d_mutex_lock(); 252 if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc))) 253 { 254 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); 255 desc->Type = D3DRTYPE_SURFACE; 256 desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage); 257 desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage); 258 desc->Size = wined3d_desc.size; 259 desc->MultiSampleType = wined3d_desc.multisample_type; 260 desc->Width = wined3d_desc.width; 261 desc->Height = wined3d_desc.height; 262 } 263 wined3d_mutex_unlock(); 264 265 return hr; 266 } 267 268 static HRESULT WINAPI d3d8_texture_2d_GetSurfaceLevel(IDirect3DTexture8 *iface, 269 UINT level, IDirect3DSurface8 **surface) 270 { 271 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface); 272 struct d3d8_surface *surface_impl; 273 274 TRACE("iface %p, level %u, surface %p.\n", iface, level, surface); 275 276 wined3d_mutex_lock(); 277 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) 278 { 279 wined3d_mutex_unlock(); 280 return D3DERR_INVALIDCALL; 281 } 282 283 *surface = &surface_impl->IDirect3DSurface8_iface; 284 IDirect3DSurface8_AddRef(*surface); 285 wined3d_mutex_unlock(); 286 287 return D3D_OK; 288 } 289 290 static HRESULT WINAPI d3d8_texture_2d_LockRect(IDirect3DTexture8 *iface, UINT level, 291 D3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags) 292 { 293 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface); 294 struct d3d8_surface *surface_impl; 295 HRESULT hr; 296 297 TRACE("iface %p, level %u, locked_rect %p, rect %p, flags %#x.\n", 298 iface, level, locked_rect, rect, flags); 299 300 wined3d_mutex_lock(); 301 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) 302 hr = D3DERR_INVALIDCALL; 303 else 304 hr = IDirect3DSurface8_LockRect(&surface_impl->IDirect3DSurface8_iface, locked_rect, rect, flags); 305 wined3d_mutex_unlock(); 306 307 return hr; 308 } 309 310 static HRESULT WINAPI d3d8_texture_2d_UnlockRect(IDirect3DTexture8 *iface, UINT level) 311 { 312 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface); 313 struct d3d8_surface *surface_impl; 314 HRESULT hr; 315 316 TRACE("iface %p, level %u.\n", iface, level); 317 318 wined3d_mutex_lock(); 319 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) 320 hr = D3DERR_INVALIDCALL; 321 else 322 hr = IDirect3DSurface8_UnlockRect(&surface_impl->IDirect3DSurface8_iface); 323 wined3d_mutex_unlock(); 324 325 return hr; 326 } 327 328 static HRESULT WINAPI d3d8_texture_2d_AddDirtyRect(IDirect3DTexture8 *iface, const RECT *dirty_rect) 329 { 330 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface); 331 HRESULT hr; 332 333 TRACE("iface %p, dirty_rect %s.\n", 334 iface, wine_dbgstr_rect(dirty_rect)); 335 336 wined3d_mutex_lock(); 337 if (!dirty_rect) 338 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, NULL); 339 else 340 { 341 struct wined3d_box dirty_region; 342 343 wined3d_box_set(&dirty_region, dirty_rect->left, dirty_rect->top, dirty_rect->right, dirty_rect->bottom, 0, 1); 344 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, &dirty_region); 345 } 346 wined3d_mutex_unlock(); 347 348 return hr; 349 } 350 351 static const IDirect3DTexture8Vtbl Direct3DTexture8_Vtbl = 352 { 353 /* IUnknown */ 354 d3d8_texture_2d_QueryInterface, 355 d3d8_texture_2d_AddRef, 356 d3d8_texture_2d_Release, 357 /* IDirect3DResource8 */ 358 d3d8_texture_2d_GetDevice, 359 d3d8_texture_2d_SetPrivateData, 360 d3d8_texture_2d_GetPrivateData, 361 d3d8_texture_2d_FreePrivateData, 362 d3d8_texture_2d_SetPriority, 363 d3d8_texture_2d_GetPriority, 364 d3d8_texture_2d_PreLoad, 365 d3d8_texture_2d_GetType, 366 /* IDirect3dBaseTexture8 */ 367 d3d8_texture_2d_SetLOD, 368 d3d8_texture_2d_GetLOD, 369 d3d8_texture_2d_GetLevelCount, 370 /* IDirect3DTexture8 */ 371 d3d8_texture_2d_GetLevelDesc, 372 d3d8_texture_2d_GetSurfaceLevel, 373 d3d8_texture_2d_LockRect, 374 d3d8_texture_2d_UnlockRect, 375 d3d8_texture_2d_AddDirtyRect, 376 }; 377 378 static HRESULT WINAPI d3d8_texture_cube_QueryInterface(IDirect3DCubeTexture8 *iface, REFIID riid, void **out) 379 { 380 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); 381 382 if (IsEqualGUID(riid, &IID_IDirect3DCubeTexture8) 383 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture8) 384 || IsEqualGUID(riid, &IID_IDirect3DResource8) 385 || IsEqualGUID(riid, &IID_IUnknown)) 386 { 387 IDirect3DCubeTexture8_AddRef(iface); 388 *out = iface; 389 return S_OK; 390 } 391 392 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); 393 394 *out = NULL; 395 return E_NOINTERFACE; 396 } 397 398 static ULONG WINAPI d3d8_texture_cube_AddRef(IDirect3DCubeTexture8 *iface) 399 { 400 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface); 401 ULONG ref = InterlockedIncrement(&texture->resource.refcount); 402 403 TRACE("%p increasing refcount to %u.\n", iface, ref); 404 405 if (ref == 1) 406 { 407 struct d3d8_surface *surface; 408 409 IDirect3DDevice8_AddRef(texture->parent_device); 410 wined3d_mutex_lock(); 411 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d8_surface, rtv_entry) 412 { 413 wined3d_rendertarget_view_incref(surface->wined3d_rtv); 414 } 415 wined3d_texture_incref(texture->wined3d_texture); 416 wined3d_mutex_unlock(); 417 } 418 419 return ref; 420 } 421 422 static ULONG WINAPI d3d8_texture_cube_Release(IDirect3DCubeTexture8 *iface) 423 { 424 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface); 425 ULONG ref = InterlockedDecrement(&texture->resource.refcount); 426 427 TRACE("%p decreasing refcount to %u.\n", iface, ref); 428 429 if (!ref) 430 { 431 IDirect3DDevice8 *parent_device = texture->parent_device; 432 struct d3d8_surface *surface; 433 434 TRACE("Releasing child %p.\n", texture->wined3d_texture); 435 436 wined3d_mutex_lock(); 437 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d8_surface, rtv_entry) 438 { 439 wined3d_rendertarget_view_decref(surface->wined3d_rtv); 440 } 441 wined3d_texture_decref(texture->wined3d_texture); 442 wined3d_mutex_unlock(); 443 444 /* Release the device last, as it may cause the device to be destroyed. */ 445 IDirect3DDevice8_Release(parent_device); 446 } 447 return ref; 448 } 449 450 static HRESULT WINAPI d3d8_texture_cube_GetDevice(IDirect3DCubeTexture8 *iface, IDirect3DDevice8 **device) 451 { 452 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface); 453 454 TRACE("iface %p, device %p.\n", iface, device); 455 456 *device = texture->parent_device; 457 IDirect3DDevice8_AddRef(*device); 458 459 TRACE("Returning device %p.\n", *device); 460 461 return D3D_OK; 462 } 463 464 static HRESULT WINAPI d3d8_texture_cube_SetPrivateData(IDirect3DCubeTexture8 *iface, 465 REFGUID guid, const void *data, DWORD data_size, DWORD flags) 466 { 467 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface); 468 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n", 469 iface, debugstr_guid(guid), data, data_size, flags); 470 471 return d3d8_resource_set_private_data(&texture->resource, guid, data, data_size, flags); 472 } 473 474 static HRESULT WINAPI d3d8_texture_cube_GetPrivateData(IDirect3DCubeTexture8 *iface, 475 REFGUID guid, void *data, DWORD *data_size) 476 { 477 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface); 478 TRACE("iface %p, guid %s, data %p, data_size %p.\n", 479 iface, debugstr_guid(guid), data, data_size); 480 481 return d3d8_resource_get_private_data(&texture->resource, guid, data, data_size); 482 } 483 484 static HRESULT WINAPI d3d8_texture_cube_FreePrivateData(IDirect3DCubeTexture8 *iface, REFGUID guid) 485 { 486 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface); 487 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid)); 488 489 return d3d8_resource_free_private_data(&texture->resource, guid); 490 } 491 492 static DWORD WINAPI d3d8_texture_cube_SetPriority(IDirect3DCubeTexture8 *iface, DWORD priority) 493 { 494 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface); 495 struct wined3d_resource *resource; 496 DWORD ret; 497 498 TRACE("iface %p, priority %u.\n", iface, priority); 499 500 wined3d_mutex_lock(); 501 resource = wined3d_texture_get_resource(texture->wined3d_texture); 502 ret = wined3d_resource_set_priority(resource, priority); 503 wined3d_mutex_unlock(); 504 505 return ret; 506 } 507 508 static DWORD WINAPI d3d8_texture_cube_GetPriority(IDirect3DCubeTexture8 *iface) 509 { 510 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface); 511 const struct wined3d_resource *resource; 512 DWORD ret; 513 514 TRACE("iface %p.\n", iface); 515 516 wined3d_mutex_lock(); 517 resource = wined3d_texture_get_resource(texture->wined3d_texture); 518 ret = wined3d_resource_get_priority(resource); 519 wined3d_mutex_unlock(); 520 521 return ret; 522 } 523 524 static void WINAPI d3d8_texture_cube_PreLoad(IDirect3DCubeTexture8 *iface) 525 { 526 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface); 527 528 TRACE("iface %p.\n", iface); 529 530 wined3d_mutex_lock(); 531 wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture)); 532 wined3d_mutex_unlock(); 533 } 534 535 static D3DRESOURCETYPE WINAPI d3d8_texture_cube_GetType(IDirect3DCubeTexture8 *iface) 536 { 537 TRACE("iface %p.\n", iface); 538 539 return D3DRTYPE_CUBETEXTURE; 540 } 541 542 static DWORD WINAPI d3d8_texture_cube_SetLOD(IDirect3DCubeTexture8 *iface, DWORD lod) 543 { 544 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface); 545 DWORD ret; 546 547 TRACE("iface %p, lod %u.\n", iface, lod); 548 549 wined3d_mutex_lock(); 550 ret = wined3d_texture_set_lod(texture->wined3d_texture, lod); 551 wined3d_mutex_unlock(); 552 553 return ret; 554 } 555 556 static DWORD WINAPI d3d8_texture_cube_GetLOD(IDirect3DCubeTexture8 *iface) 557 { 558 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface); 559 DWORD ret; 560 561 TRACE("iface %p.\n", iface); 562 563 wined3d_mutex_lock(); 564 ret = wined3d_texture_get_lod(texture->wined3d_texture); 565 wined3d_mutex_unlock(); 566 567 return ret; 568 } 569 570 static DWORD WINAPI d3d8_texture_cube_GetLevelCount(IDirect3DCubeTexture8 *iface) 571 { 572 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface); 573 DWORD ret; 574 575 TRACE("iface %p.\n", iface); 576 577 wined3d_mutex_lock(); 578 ret = wined3d_texture_get_level_count(texture->wined3d_texture); 579 wined3d_mutex_unlock(); 580 581 return ret; 582 } 583 584 static HRESULT WINAPI d3d8_texture_cube_GetLevelDesc(IDirect3DCubeTexture8 *iface, UINT level, D3DSURFACE_DESC *desc) 585 { 586 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface); 587 struct wined3d_sub_resource_desc wined3d_desc; 588 HRESULT hr; 589 590 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc); 591 592 wined3d_mutex_lock(); 593 if (level >= wined3d_texture_get_level_count(texture->wined3d_texture)) 594 { 595 wined3d_mutex_unlock(); 596 return D3DERR_INVALIDCALL; 597 } 598 599 if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc))) 600 { 601 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); 602 desc->Type = D3DRTYPE_SURFACE; 603 desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage); 604 desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage); 605 desc->Size = wined3d_desc.size; 606 desc->MultiSampleType = wined3d_desc.multisample_type; 607 desc->Width = wined3d_desc.width; 608 desc->Height = wined3d_desc.height; 609 } 610 wined3d_mutex_unlock(); 611 612 return hr; 613 } 614 615 static HRESULT WINAPI d3d8_texture_cube_GetCubeMapSurface(IDirect3DCubeTexture8 *iface, 616 D3DCUBEMAP_FACES face, UINT level, IDirect3DSurface8 **surface) 617 { 618 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface); 619 struct d3d8_surface *surface_impl; 620 UINT sub_resource_idx; 621 DWORD level_count; 622 623 TRACE("iface %p, face %#x, level %u, surface %p.\n", iface, face, level, surface); 624 625 wined3d_mutex_lock(); 626 level_count = wined3d_texture_get_level_count(texture->wined3d_texture); 627 if (level >= level_count) 628 { 629 wined3d_mutex_unlock(); 630 return D3DERR_INVALIDCALL; 631 } 632 633 sub_resource_idx = level_count * face + level; 634 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx))) 635 { 636 wined3d_mutex_unlock(); 637 return D3DERR_INVALIDCALL; 638 } 639 640 *surface = &surface_impl->IDirect3DSurface8_iface; 641 IDirect3DSurface8_AddRef(*surface); 642 wined3d_mutex_unlock(); 643 644 return D3D_OK; 645 } 646 647 static HRESULT WINAPI d3d8_texture_cube_LockRect(IDirect3DCubeTexture8 *iface, 648 D3DCUBEMAP_FACES face, UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect, 649 DWORD flags) 650 { 651 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface); 652 struct d3d8_surface *surface_impl; 653 UINT sub_resource_idx; 654 HRESULT hr; 655 656 TRACE("iface %p, face %#x, level %u, locked_rect %p, rect %p, flags %#x.\n", 657 iface, face, level, locked_rect, rect, flags); 658 659 wined3d_mutex_lock(); 660 sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level; 661 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx))) 662 hr = D3DERR_INVALIDCALL; 663 else 664 hr = IDirect3DSurface8_LockRect(&surface_impl->IDirect3DSurface8_iface, locked_rect, rect, flags); 665 wined3d_mutex_unlock(); 666 667 return hr; 668 } 669 670 static HRESULT WINAPI d3d8_texture_cube_UnlockRect(IDirect3DCubeTexture8 *iface, 671 D3DCUBEMAP_FACES face, UINT level) 672 { 673 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface); 674 struct d3d8_surface *surface_impl; 675 UINT sub_resource_idx; 676 HRESULT hr; 677 678 TRACE("iface %p, face %#x, level %u.\n", iface, face, level); 679 680 wined3d_mutex_lock(); 681 sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level; 682 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx))) 683 hr = D3DERR_INVALIDCALL; 684 else 685 hr = IDirect3DSurface8_UnlockRect(&surface_impl->IDirect3DSurface8_iface); 686 wined3d_mutex_unlock(); 687 688 return hr; 689 } 690 691 static HRESULT WINAPI d3d8_texture_cube_AddDirtyRect(IDirect3DCubeTexture8 *iface, 692 D3DCUBEMAP_FACES face, const RECT *dirty_rect) 693 { 694 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface); 695 HRESULT hr; 696 697 TRACE("iface %p, face %#x, dirty_rect %s.\n", 698 iface, face, wine_dbgstr_rect(dirty_rect)); 699 700 wined3d_mutex_lock(); 701 if (!dirty_rect) 702 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, NULL); 703 else 704 { 705 struct wined3d_box dirty_region; 706 707 wined3d_box_set(&dirty_region, dirty_rect->left, dirty_rect->top, dirty_rect->right, dirty_rect->bottom, 0, 1); 708 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, &dirty_region); 709 } 710 wined3d_mutex_unlock(); 711 712 return hr; 713 } 714 715 static const IDirect3DCubeTexture8Vtbl Direct3DCubeTexture8_Vtbl = 716 { 717 /* IUnknown */ 718 d3d8_texture_cube_QueryInterface, 719 d3d8_texture_cube_AddRef, 720 d3d8_texture_cube_Release, 721 /* IDirect3DResource8 */ 722 d3d8_texture_cube_GetDevice, 723 d3d8_texture_cube_SetPrivateData, 724 d3d8_texture_cube_GetPrivateData, 725 d3d8_texture_cube_FreePrivateData, 726 d3d8_texture_cube_SetPriority, 727 d3d8_texture_cube_GetPriority, 728 d3d8_texture_cube_PreLoad, 729 d3d8_texture_cube_GetType, 730 /* IDirect3DBaseTexture8 */ 731 d3d8_texture_cube_SetLOD, 732 d3d8_texture_cube_GetLOD, 733 d3d8_texture_cube_GetLevelCount, 734 /* IDirect3DCubeTexture8 */ 735 d3d8_texture_cube_GetLevelDesc, 736 d3d8_texture_cube_GetCubeMapSurface, 737 d3d8_texture_cube_LockRect, 738 d3d8_texture_cube_UnlockRect, 739 d3d8_texture_cube_AddDirtyRect, 740 }; 741 742 static HRESULT WINAPI d3d8_texture_3d_QueryInterface(IDirect3DVolumeTexture8 *iface, REFIID riid, void **out) 743 { 744 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); 745 746 if (IsEqualGUID(riid, &IID_IDirect3DVolumeTexture8) 747 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture8) 748 || IsEqualGUID(riid, &IID_IDirect3DResource8) 749 || IsEqualGUID(riid, &IID_IUnknown)) 750 { 751 IDirect3DVolumeTexture8_AddRef(iface); 752 *out = iface; 753 return S_OK; 754 } 755 756 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); 757 758 *out = NULL; 759 return E_NOINTERFACE; 760 } 761 762 static ULONG WINAPI d3d8_texture_3d_AddRef(IDirect3DVolumeTexture8 *iface) 763 { 764 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); 765 ULONG ref = InterlockedIncrement(&texture->resource.refcount); 766 767 TRACE("%p increasing refcount to %u.\n", iface, ref); 768 769 if (ref == 1) 770 { 771 IDirect3DDevice8_AddRef(texture->parent_device); 772 wined3d_mutex_lock(); 773 wined3d_texture_incref(texture->wined3d_texture); 774 wined3d_mutex_unlock(); 775 } 776 777 return ref; 778 } 779 780 static ULONG WINAPI d3d8_texture_3d_Release(IDirect3DVolumeTexture8 *iface) 781 { 782 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); 783 ULONG ref = InterlockedDecrement(&texture->resource.refcount); 784 785 TRACE("%p decreasing refcount to %u.\n", iface, ref); 786 787 if (!ref) 788 { 789 IDirect3DDevice8 *parent_device = texture->parent_device; 790 791 wined3d_mutex_lock(); 792 wined3d_texture_decref(texture->wined3d_texture); 793 wined3d_mutex_unlock(); 794 795 /* Release the device last, as it may cause the device to be destroyed. */ 796 IDirect3DDevice8_Release(parent_device); 797 } 798 return ref; 799 } 800 801 static HRESULT WINAPI d3d8_texture_3d_GetDevice(IDirect3DVolumeTexture8 *iface, IDirect3DDevice8 **device) 802 { 803 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); 804 805 TRACE("iface %p, device %p.\n", iface, device); 806 807 *device = texture->parent_device; 808 IDirect3DDevice8_AddRef(*device); 809 810 TRACE("Returning device %p.\n", *device); 811 812 return D3D_OK; 813 } 814 815 static HRESULT WINAPI d3d8_texture_3d_SetPrivateData(IDirect3DVolumeTexture8 *iface, 816 REFGUID guid, const void *data, DWORD data_size, DWORD flags) 817 { 818 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); 819 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n", 820 iface, debugstr_guid(guid), data, data_size, flags); 821 822 return d3d8_resource_set_private_data(&texture->resource, guid, data, data_size, flags); 823 } 824 825 static HRESULT WINAPI d3d8_texture_3d_GetPrivateData(IDirect3DVolumeTexture8 *iface, 826 REFGUID guid, void *data, DWORD *data_size) 827 { 828 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); 829 TRACE("iface %p, guid %s, data %p, data_size %p.\n", 830 iface, debugstr_guid(guid), data, data_size); 831 832 return d3d8_resource_get_private_data(&texture->resource, guid, data, data_size); 833 } 834 835 static HRESULT WINAPI d3d8_texture_3d_FreePrivateData(IDirect3DVolumeTexture8 *iface, REFGUID guid) 836 { 837 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); 838 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid)); 839 840 return d3d8_resource_free_private_data(&texture->resource, guid); 841 } 842 843 static DWORD WINAPI d3d8_texture_3d_SetPriority(IDirect3DVolumeTexture8 *iface, DWORD priority) 844 { 845 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); 846 struct wined3d_resource *resource; 847 DWORD ret; 848 849 TRACE("iface %p, priority %u.\n", iface, priority); 850 851 wined3d_mutex_lock(); 852 resource = wined3d_texture_get_resource(texture->wined3d_texture); 853 ret = wined3d_resource_set_priority(resource, priority); 854 wined3d_mutex_unlock(); 855 856 return ret; 857 } 858 859 static DWORD WINAPI d3d8_texture_3d_GetPriority(IDirect3DVolumeTexture8 *iface) 860 { 861 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); 862 const struct wined3d_resource *resource; 863 DWORD ret; 864 865 TRACE("iface %p.\n", iface); 866 867 wined3d_mutex_lock(); 868 resource = wined3d_texture_get_resource(texture->wined3d_texture); 869 ret = wined3d_resource_get_priority(resource); 870 wined3d_mutex_unlock(); 871 872 return ret; 873 } 874 875 static void WINAPI d3d8_texture_3d_PreLoad(IDirect3DVolumeTexture8 *iface) 876 { 877 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); 878 879 TRACE("iface %p.\n", iface); 880 881 wined3d_mutex_lock(); 882 wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture)); 883 wined3d_mutex_unlock(); 884 } 885 886 static D3DRESOURCETYPE WINAPI d3d8_texture_3d_GetType(IDirect3DVolumeTexture8 *iface) 887 { 888 TRACE("iface %p.\n", iface); 889 890 return D3DRTYPE_VOLUMETEXTURE; 891 } 892 893 static DWORD WINAPI d3d8_texture_3d_SetLOD(IDirect3DVolumeTexture8 *iface, DWORD lod) 894 { 895 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); 896 DWORD ret; 897 898 TRACE("iface %p, lod %u.\n", iface, lod); 899 900 wined3d_mutex_lock(); 901 ret = wined3d_texture_set_lod(texture->wined3d_texture, lod); 902 wined3d_mutex_unlock(); 903 904 return ret; 905 } 906 907 static DWORD WINAPI d3d8_texture_3d_GetLOD(IDirect3DVolumeTexture8 *iface) 908 { 909 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); 910 DWORD ret; 911 912 TRACE("iface %p.\n", iface); 913 914 wined3d_mutex_lock(); 915 ret = wined3d_texture_get_lod(texture->wined3d_texture); 916 wined3d_mutex_unlock(); 917 918 return ret; 919 } 920 921 static DWORD WINAPI d3d8_texture_3d_GetLevelCount(IDirect3DVolumeTexture8 *iface) 922 { 923 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); 924 DWORD ret; 925 926 TRACE("iface %p.\n", iface); 927 928 wined3d_mutex_lock(); 929 ret = wined3d_texture_get_level_count(texture->wined3d_texture); 930 wined3d_mutex_unlock(); 931 932 return ret; 933 } 934 935 static HRESULT WINAPI d3d8_texture_3d_GetLevelDesc(IDirect3DVolumeTexture8 *iface, UINT level, D3DVOLUME_DESC *desc) 936 { 937 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); 938 struct wined3d_sub_resource_desc wined3d_desc; 939 HRESULT hr; 940 941 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc); 942 943 wined3d_mutex_lock(); 944 if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc))) 945 { 946 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); 947 desc->Type = D3DRTYPE_VOLUME; 948 desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage); 949 desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage); 950 desc->Size = wined3d_desc.size; 951 desc->Width = wined3d_desc.width; 952 desc->Height = wined3d_desc.height; 953 desc->Depth = wined3d_desc.depth; 954 } 955 wined3d_mutex_unlock(); 956 957 return hr; 958 } 959 960 static HRESULT WINAPI d3d8_texture_3d_GetVolumeLevel(IDirect3DVolumeTexture8 *iface, 961 UINT level, IDirect3DVolume8 **volume) 962 { 963 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); 964 struct d3d8_volume *volume_impl; 965 966 TRACE("iface %p, level %u, volume %p.\n", iface, level, volume); 967 968 wined3d_mutex_lock(); 969 if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) 970 { 971 wined3d_mutex_unlock(); 972 return D3DERR_INVALIDCALL; 973 } 974 975 *volume = &volume_impl->IDirect3DVolume8_iface; 976 IDirect3DVolume8_AddRef(*volume); 977 wined3d_mutex_unlock(); 978 979 return D3D_OK; 980 } 981 982 static HRESULT WINAPI d3d8_texture_3d_LockBox(IDirect3DVolumeTexture8 *iface, 983 UINT level, D3DLOCKED_BOX *locked_box, const D3DBOX *box, DWORD flags) 984 { 985 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); 986 struct d3d8_volume *volume_impl; 987 HRESULT hr; 988 989 TRACE("iface %p, level %u, locked_box %p, box %p, flags %#x.\n", 990 iface, level, locked_box, box, flags); 991 992 wined3d_mutex_lock(); 993 if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) 994 hr = D3DERR_INVALIDCALL; 995 else 996 hr = IDirect3DVolume8_LockBox(&volume_impl->IDirect3DVolume8_iface, locked_box, box, flags); 997 wined3d_mutex_unlock(); 998 999 return hr; 1000 } 1001 1002 static HRESULT WINAPI d3d8_texture_3d_UnlockBox(IDirect3DVolumeTexture8 *iface, UINT level) 1003 { 1004 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); 1005 struct d3d8_volume *volume_impl; 1006 HRESULT hr; 1007 1008 TRACE("iface %p, level %u.\n", iface, level); 1009 1010 wined3d_mutex_lock(); 1011 if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) 1012 hr = D3DERR_INVALIDCALL; 1013 else 1014 hr = IDirect3DVolume8_UnlockBox(&volume_impl->IDirect3DVolume8_iface); 1015 wined3d_mutex_unlock(); 1016 1017 return hr; 1018 } 1019 1020 static HRESULT WINAPI d3d8_texture_3d_AddDirtyBox(IDirect3DVolumeTexture8 *iface, const D3DBOX *dirty_box) 1021 { 1022 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); 1023 HRESULT hr; 1024 1025 TRACE("iface %p, dirty_box %p.\n", iface, dirty_box); 1026 1027 wined3d_mutex_lock(); 1028 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, (const struct wined3d_box *)dirty_box); 1029 wined3d_mutex_unlock(); 1030 1031 return hr; 1032 } 1033 1034 static const IDirect3DVolumeTexture8Vtbl Direct3DVolumeTexture8_Vtbl = 1035 { 1036 /* IUnknown */ 1037 d3d8_texture_3d_QueryInterface, 1038 d3d8_texture_3d_AddRef, 1039 d3d8_texture_3d_Release, 1040 /* IDirect3DResource8 */ 1041 d3d8_texture_3d_GetDevice, 1042 d3d8_texture_3d_SetPrivateData, 1043 d3d8_texture_3d_GetPrivateData, 1044 d3d8_texture_3d_FreePrivateData, 1045 d3d8_texture_3d_SetPriority, 1046 d3d8_texture_3d_GetPriority, 1047 d3d8_texture_3d_PreLoad, 1048 d3d8_texture_3d_GetType, 1049 /* IDirect3DBaseTexture8 */ 1050 d3d8_texture_3d_SetLOD, 1051 d3d8_texture_3d_GetLOD, 1052 d3d8_texture_3d_GetLevelCount, 1053 /* IDirect3DVolumeTexture8 */ 1054 d3d8_texture_3d_GetLevelDesc, 1055 d3d8_texture_3d_GetVolumeLevel, 1056 d3d8_texture_3d_LockBox, 1057 d3d8_texture_3d_UnlockBox, 1058 d3d8_texture_3d_AddDirtyBox 1059 }; 1060 1061 struct d3d8_texture *unsafe_impl_from_IDirect3DBaseTexture8(IDirect3DBaseTexture8 *iface) 1062 { 1063 if (!iface) 1064 return NULL; 1065 1066 /* SetTexture() in particular doesn't do a lot of validation on the pointer 1067 * that gets passed in, and passing an invalid pointer works as long as the 1068 * application doesn't try to actually render anything with it, so we print 1069 * a WARN and return NULL instead of having the usual assert() here. 1070 * One application affected by this is Fishdom 2. */ 1071 if (iface->lpVtbl != (const IDirect3DBaseTexture8Vtbl *)&Direct3DTexture8_Vtbl 1072 && iface->lpVtbl != (const IDirect3DBaseTexture8Vtbl *)&Direct3DCubeTexture8_Vtbl 1073 && iface->lpVtbl != (const IDirect3DBaseTexture8Vtbl *)&Direct3DVolumeTexture8_Vtbl) 1074 { 1075 WARN("%p is not a valid IDirect3DBaseTexture8 interface.\n", iface); 1076 return NULL; 1077 } 1078 1079 return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); 1080 } 1081 1082 static void STDMETHODCALLTYPE d3d8_texture_wined3d_object_destroyed(void *parent) 1083 { 1084 struct d3d8_texture *texture = parent; 1085 d3d8_resource_cleanup(&texture->resource); 1086 heap_free(texture); 1087 } 1088 1089 static const struct wined3d_parent_ops d3d8_texture_wined3d_parent_ops = 1090 { 1091 d3d8_texture_wined3d_object_destroyed, 1092 }; 1093 1094 HRESULT texture_init(struct d3d8_texture *texture, struct d3d8_device *device, 1095 UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool) 1096 { 1097 struct wined3d_resource_desc desc; 1098 DWORD flags = 0; 1099 HRESULT hr; 1100 1101 texture->IDirect3DBaseTexture8_iface.lpVtbl = (const IDirect3DBaseTexture8Vtbl *)&Direct3DTexture8_Vtbl; 1102 d3d8_resource_init(&texture->resource); 1103 list_init(&texture->rtv_list); 1104 1105 desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; 1106 desc.format = wined3dformat_from_d3dformat(format); 1107 desc.multisample_type = WINED3D_MULTISAMPLE_NONE; 1108 desc.multisample_quality = 0; 1109 desc.usage = usage & WINED3DUSAGE_MASK; 1110 desc.usage |= WINED3DUSAGE_TEXTURE; 1111 if (pool == D3DPOOL_SCRATCH) 1112 desc.usage |= WINED3DUSAGE_SCRATCH; 1113 desc.access = wined3daccess_from_d3dpool(pool, usage) 1114 | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; 1115 desc.width = width; 1116 desc.height = height; 1117 desc.depth = 1; 1118 desc.size = 0; 1119 1120 if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC)) 1121 flags |= WINED3D_TEXTURE_CREATE_MAPPABLE; 1122 1123 if (!levels) 1124 levels = wined3d_log2i(max(width, height)) + 1; 1125 1126 wined3d_mutex_lock(); 1127 hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, flags, 1128 NULL, texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture); 1129 wined3d_mutex_unlock(); 1130 if (FAILED(hr)) 1131 { 1132 WARN("Failed to create wined3d texture, hr %#x.\n", hr); 1133 return hr; 1134 } 1135 1136 texture->parent_device = &device->IDirect3DDevice8_iface; 1137 IDirect3DDevice8_AddRef(texture->parent_device); 1138 1139 return D3D_OK; 1140 } 1141 1142 HRESULT cubetexture_init(struct d3d8_texture *texture, struct d3d8_device *device, 1143 UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool) 1144 { 1145 struct wined3d_resource_desc desc; 1146 DWORD flags = 0; 1147 HRESULT hr; 1148 1149 texture->IDirect3DBaseTexture8_iface.lpVtbl = (const IDirect3DBaseTexture8Vtbl *)&Direct3DCubeTexture8_Vtbl; 1150 d3d8_resource_init(&texture->resource); 1151 list_init(&texture->rtv_list); 1152 1153 desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; 1154 desc.format = wined3dformat_from_d3dformat(format); 1155 desc.multisample_type = WINED3D_MULTISAMPLE_NONE; 1156 desc.multisample_quality = 0; 1157 desc.usage = usage & WINED3DUSAGE_MASK; 1158 desc.usage |= WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_TEXTURE; 1159 if (pool == D3DPOOL_SCRATCH) 1160 desc.usage |= WINED3DUSAGE_SCRATCH; 1161 desc.access = wined3daccess_from_d3dpool(pool, usage) 1162 | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W; 1163 desc.width = edge_length; 1164 desc.height = edge_length; 1165 desc.depth = 1; 1166 desc.size = 0; 1167 1168 if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC)) 1169 flags |= WINED3D_TEXTURE_CREATE_MAPPABLE; 1170 1171 if (!levels) 1172 levels = wined3d_log2i(edge_length) + 1; 1173 1174 wined3d_mutex_lock(); 1175 hr = wined3d_texture_create(device->wined3d_device, &desc, 6, levels, flags, 1176 NULL, texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture); 1177 wined3d_mutex_unlock(); 1178 if (FAILED(hr)) 1179 { 1180 WARN("Failed to create wined3d cube texture, hr %#x.\n", hr); 1181 return hr; 1182 } 1183 1184 texture->parent_device = &device->IDirect3DDevice8_iface; 1185 IDirect3DDevice8_AddRef(texture->parent_device); 1186 1187 return D3D_OK; 1188 } 1189 1190 HRESULT volumetexture_init(struct d3d8_texture *texture, struct d3d8_device *device, 1191 UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool) 1192 { 1193 struct wined3d_resource_desc desc; 1194 HRESULT hr; 1195 1196 texture->IDirect3DBaseTexture8_iface.lpVtbl = (const IDirect3DBaseTexture8Vtbl *)&Direct3DVolumeTexture8_Vtbl; 1197 d3d8_resource_init(&texture->resource); 1198 list_init(&texture->rtv_list); 1199 1200 desc.resource_type = WINED3D_RTYPE_TEXTURE_3D; 1201 desc.format = wined3dformat_from_d3dformat(format); 1202 desc.multisample_type = WINED3D_MULTISAMPLE_NONE; 1203 desc.multisample_quality = 0; 1204 desc.usage = usage & WINED3DUSAGE_MASK; 1205 desc.usage |= WINED3DUSAGE_TEXTURE; 1206 if (pool == D3DPOOL_SCRATCH) 1207 desc.usage |= WINED3DUSAGE_SCRATCH; 1208 desc.access = wined3daccess_from_d3dpool(pool, usage); 1209 desc.width = width; 1210 desc.height = height; 1211 desc.depth = depth; 1212 desc.size = 0; 1213 1214 if (!levels) 1215 levels = wined3d_log2i(max(max(width, height), depth)) + 1; 1216 1217 wined3d_mutex_lock(); 1218 hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, 0, 1219 NULL, texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture); 1220 wined3d_mutex_unlock(); 1221 if (FAILED(hr)) 1222 { 1223 WARN("Failed to create wined3d volume texture, hr %#x.\n", hr); 1224 return hr; 1225 } 1226 1227 texture->parent_device = &device->IDirect3DDevice8_iface; 1228 IDirect3DDevice8_AddRef(texture->parent_device); 1229 1230 return D3D_OK; 1231 } 1232