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