1 /* 2 * Copyright 2002-2005 Jason Edmeades 3 * Copyright 2002-2005 Raphael Junqueira 4 * Copyright 2005 Oliver Stieber 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include "d3d9_private.h" 22 23 static inline struct d3d9_texture *impl_from_IDirect3DTexture9(IDirect3DTexture9 *iface) 24 { 25 return CONTAINING_RECORD((IDirect3DBaseTexture9 *)iface, struct d3d9_texture, IDirect3DBaseTexture9_iface); 26 } 27 28 static inline struct d3d9_texture *impl_from_IDirect3DCubeTexture9(IDirect3DCubeTexture9 *iface) 29 { 30 return CONTAINING_RECORD((IDirect3DBaseTexture9 *)iface, struct d3d9_texture, IDirect3DBaseTexture9_iface); 31 } 32 33 static inline struct d3d9_texture *impl_from_IDirect3DVolumeTexture9(IDirect3DVolumeTexture9 *iface) 34 { 35 return CONTAINING_RECORD((IDirect3DBaseTexture9 *)iface, struct d3d9_texture, IDirect3DBaseTexture9_iface); 36 } 37 38 static HRESULT WINAPI d3d9_texture_2d_QueryInterface(IDirect3DTexture9 *iface, REFIID riid, void **out) 39 { 40 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); 41 42 if (IsEqualGUID(riid, &IID_IDirect3DTexture9) 43 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9) 44 || IsEqualGUID(riid, &IID_IDirect3DResource9) 45 || IsEqualGUID(riid, &IID_IUnknown)) 46 { 47 IDirect3DTexture9_AddRef(iface); 48 *out = iface; 49 return S_OK; 50 } 51 52 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); 53 54 *out = NULL; 55 return E_NOINTERFACE; 56 } 57 58 static ULONG WINAPI d3d9_texture_2d_AddRef(IDirect3DTexture9 *iface) 59 { 60 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); 61 ULONG ref = InterlockedIncrement(&texture->resource.refcount); 62 63 TRACE("%p increasing refcount to %u.\n", iface, ref); 64 65 if (ref == 1) 66 { 67 struct d3d9_surface *surface; 68 69 IDirect3DDevice9Ex_AddRef(texture->parent_device); 70 wined3d_mutex_lock(); 71 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry) 72 { 73 wined3d_rendertarget_view_incref(surface->wined3d_rtv); 74 } 75 wined3d_texture_incref(texture->wined3d_texture); 76 wined3d_mutex_unlock(); 77 } 78 79 return ref; 80 } 81 82 static ULONG WINAPI d3d9_texture_2d_Release(IDirect3DTexture9 *iface) 83 { 84 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); 85 ULONG ref = InterlockedDecrement(&texture->resource.refcount); 86 87 TRACE("%p decreasing refcount to %u.\n", iface, ref); 88 89 if (!ref) 90 { 91 IDirect3DDevice9Ex *parent_device = texture->parent_device; 92 struct d3d9_surface *surface; 93 94 wined3d_mutex_lock(); 95 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry) 96 { 97 wined3d_rendertarget_view_decref(surface->wined3d_rtv); 98 } 99 wined3d_texture_decref(texture->wined3d_texture); 100 wined3d_mutex_unlock(); 101 102 /* Release the device last, as it may cause the device to be destroyed. */ 103 IDirect3DDevice9Ex_Release(parent_device); 104 } 105 return ref; 106 } 107 108 static HRESULT WINAPI d3d9_texture_2d_GetDevice(IDirect3DTexture9 *iface, IDirect3DDevice9 **device) 109 { 110 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); 111 112 TRACE("iface %p, device %p.\n", iface, device); 113 114 *device = (IDirect3DDevice9 *)texture->parent_device; 115 IDirect3DDevice9_AddRef(*device); 116 117 TRACE("Returning device %p.\n", *device); 118 119 return D3D_OK; 120 } 121 122 static HRESULT WINAPI d3d9_texture_2d_SetPrivateData(IDirect3DTexture9 *iface, 123 REFGUID guid, const void *data, DWORD data_size, DWORD flags) 124 { 125 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); 126 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n", 127 iface, debugstr_guid(guid), data, data_size, flags); 128 129 return d3d9_resource_set_private_data(&texture->resource, guid, data, data_size, flags); 130 } 131 132 static HRESULT WINAPI d3d9_texture_2d_GetPrivateData(IDirect3DTexture9 *iface, 133 REFGUID guid, void *data, DWORD *data_size) 134 { 135 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); 136 TRACE("iface %p, guid %s, data %p, data_size %p.\n", 137 iface, debugstr_guid(guid), data, data_size); 138 139 return d3d9_resource_get_private_data(&texture->resource, guid, data, data_size); 140 } 141 142 static HRESULT WINAPI d3d9_texture_2d_FreePrivateData(IDirect3DTexture9 *iface, REFGUID guid) 143 { 144 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); 145 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid)); 146 147 return d3d9_resource_free_private_data(&texture->resource, guid); 148 } 149 150 static DWORD WINAPI d3d9_texture_2d_SetPriority(IDirect3DTexture9 *iface, DWORD priority) 151 { 152 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); 153 struct wined3d_resource *resource; 154 DWORD ret; 155 156 TRACE("iface %p, priority %u.\n", iface, priority); 157 158 wined3d_mutex_lock(); 159 resource = wined3d_texture_get_resource(texture->wined3d_texture); 160 ret = wined3d_resource_set_priority(resource, priority); 161 wined3d_mutex_unlock(); 162 163 return ret; 164 } 165 166 static DWORD WINAPI d3d9_texture_2d_GetPriority(IDirect3DTexture9 *iface) 167 { 168 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); 169 const struct wined3d_resource *resource; 170 DWORD ret; 171 172 TRACE("iface %p.\n", iface); 173 174 wined3d_mutex_lock(); 175 resource = wined3d_texture_get_resource(texture->wined3d_texture); 176 ret = wined3d_resource_get_priority(resource); 177 wined3d_mutex_unlock(); 178 179 return ret; 180 } 181 182 static void WINAPI d3d9_texture_2d_PreLoad(IDirect3DTexture9 *iface) 183 { 184 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); 185 186 TRACE("iface %p.\n", iface); 187 188 wined3d_mutex_lock(); 189 wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture)); 190 wined3d_mutex_unlock(); 191 } 192 193 static D3DRESOURCETYPE WINAPI d3d9_texture_2d_GetType(IDirect3DTexture9 *iface) 194 { 195 TRACE("iface %p.\n", iface); 196 197 return D3DRTYPE_TEXTURE; 198 } 199 200 static DWORD WINAPI d3d9_texture_2d_SetLOD(IDirect3DTexture9 *iface, DWORD lod) 201 { 202 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); 203 DWORD ret; 204 205 TRACE("iface %p, lod %u.\n", iface, lod); 206 207 wined3d_mutex_lock(); 208 ret = wined3d_texture_set_lod(texture->wined3d_texture, lod); 209 wined3d_mutex_unlock(); 210 211 return ret; 212 } 213 214 static DWORD WINAPI d3d9_texture_2d_GetLOD(IDirect3DTexture9 *iface) 215 { 216 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); 217 DWORD ret; 218 219 TRACE("iface %p.\n", iface); 220 221 wined3d_mutex_lock(); 222 ret = wined3d_texture_get_lod(texture->wined3d_texture); 223 wined3d_mutex_unlock(); 224 225 return ret; 226 } 227 228 static DWORD WINAPI d3d9_texture_2d_GetLevelCount(IDirect3DTexture9 *iface) 229 { 230 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); 231 DWORD ret; 232 233 TRACE("iface %p.\n", iface); 234 235 wined3d_mutex_lock(); 236 ret = wined3d_texture_get_level_count(texture->wined3d_texture); 237 wined3d_mutex_unlock(); 238 239 return ret; 240 } 241 242 static HRESULT WINAPI d3d9_texture_2d_SetAutoGenFilterType(IDirect3DTexture9 *iface, D3DTEXTUREFILTERTYPE filter_type) 243 { 244 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); 245 HRESULT hr; 246 247 TRACE("iface %p, filter_type %#x.\n", iface, filter_type); 248 249 wined3d_mutex_lock(); 250 hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture, 251 (enum wined3d_texture_filter_type)filter_type); 252 wined3d_mutex_unlock(); 253 254 return hr; 255 } 256 257 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_2d_GetAutoGenFilterType(IDirect3DTexture9 *iface) 258 { 259 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); 260 D3DTEXTUREFILTERTYPE ret; 261 262 TRACE("iface %p.\n", iface); 263 264 wined3d_mutex_lock(); 265 ret = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture); 266 wined3d_mutex_unlock(); 267 268 return ret; 269 } 270 271 static void WINAPI d3d9_texture_2d_GenerateMipSubLevels(IDirect3DTexture9 *iface) 272 { 273 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); 274 275 TRACE("iface %p.\n", iface); 276 277 wined3d_mutex_lock(); 278 wined3d_texture_generate_mipmaps(texture->wined3d_texture); 279 wined3d_mutex_unlock(); 280 } 281 282 static HRESULT WINAPI d3d9_texture_2d_GetLevelDesc(IDirect3DTexture9 *iface, UINT level, D3DSURFACE_DESC *desc) 283 { 284 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); 285 struct wined3d_sub_resource_desc wined3d_desc; 286 HRESULT hr; 287 288 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc); 289 290 wined3d_mutex_lock(); 291 if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc))) 292 { 293 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); 294 desc->Type = D3DRTYPE_SURFACE; 295 desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK; 296 desc->Pool = wined3d_desc.pool; 297 desc->MultiSampleType = wined3d_desc.multisample_type; 298 desc->MultiSampleQuality = wined3d_desc.multisample_quality; 299 desc->Width = wined3d_desc.width; 300 desc->Height = wined3d_desc.height; 301 } 302 wined3d_mutex_unlock(); 303 304 return hr; 305 } 306 307 static HRESULT WINAPI d3d9_texture_2d_GetSurfaceLevel(IDirect3DTexture9 *iface, 308 UINT level, IDirect3DSurface9 **surface) 309 { 310 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); 311 struct d3d9_surface *surface_impl; 312 313 TRACE("iface %p, level %u, surface %p.\n", iface, level, surface); 314 315 wined3d_mutex_lock(); 316 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) 317 { 318 wined3d_mutex_unlock(); 319 return D3DERR_INVALIDCALL; 320 } 321 322 *surface = &surface_impl->IDirect3DSurface9_iface; 323 IDirect3DSurface9_AddRef(*surface); 324 wined3d_mutex_unlock(); 325 326 return D3D_OK; 327 } 328 329 static HRESULT WINAPI d3d9_texture_2d_LockRect(IDirect3DTexture9 *iface, 330 UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags) 331 { 332 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); 333 struct d3d9_surface *surface_impl; 334 HRESULT hr; 335 336 TRACE("iface %p, level %u, locked_rect %p, rect %p, flags %#x.\n", 337 iface, level, locked_rect, rect, flags); 338 339 wined3d_mutex_lock(); 340 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) 341 hr = D3DERR_INVALIDCALL; 342 else 343 hr = IDirect3DSurface9_LockRect(&surface_impl->IDirect3DSurface9_iface, locked_rect, rect, flags); 344 wined3d_mutex_unlock(); 345 346 return hr; 347 } 348 349 static HRESULT WINAPI d3d9_texture_2d_UnlockRect(IDirect3DTexture9 *iface, UINT level) 350 { 351 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); 352 struct d3d9_surface *surface_impl; 353 HRESULT hr; 354 355 TRACE("iface %p, level %u.\n", iface, level); 356 357 wined3d_mutex_lock(); 358 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) 359 hr = D3DERR_INVALIDCALL; 360 else 361 hr = IDirect3DSurface9_UnlockRect(&surface_impl->IDirect3DSurface9_iface); 362 wined3d_mutex_unlock(); 363 364 return hr; 365 } 366 367 static HRESULT WINAPI d3d9_texture_2d_AddDirtyRect(IDirect3DTexture9 *iface, const RECT *dirty_rect) 368 { 369 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); 370 HRESULT hr; 371 372 TRACE("iface %p, dirty_rect %s.\n", 373 iface, wine_dbgstr_rect(dirty_rect)); 374 375 wined3d_mutex_lock(); 376 if (!dirty_rect) 377 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, NULL); 378 else 379 { 380 struct wined3d_box dirty_region; 381 382 wined3d_box_set(&dirty_region, dirty_rect->left, dirty_rect->top, dirty_rect->right, dirty_rect->bottom, 0, 1); 383 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, &dirty_region); 384 } 385 wined3d_mutex_unlock(); 386 387 return hr; 388 } 389 390 static const IDirect3DTexture9Vtbl d3d9_texture_2d_vtbl = 391 { 392 /* IUnknown */ 393 d3d9_texture_2d_QueryInterface, 394 d3d9_texture_2d_AddRef, 395 d3d9_texture_2d_Release, 396 /* IDirect3DResource9 */ 397 d3d9_texture_2d_GetDevice, 398 d3d9_texture_2d_SetPrivateData, 399 d3d9_texture_2d_GetPrivateData, 400 d3d9_texture_2d_FreePrivateData, 401 d3d9_texture_2d_SetPriority, 402 d3d9_texture_2d_GetPriority, 403 d3d9_texture_2d_PreLoad, 404 d3d9_texture_2d_GetType, 405 /* IDirect3dBaseTexture9 */ 406 d3d9_texture_2d_SetLOD, 407 d3d9_texture_2d_GetLOD, 408 d3d9_texture_2d_GetLevelCount, 409 d3d9_texture_2d_SetAutoGenFilterType, 410 d3d9_texture_2d_GetAutoGenFilterType, 411 d3d9_texture_2d_GenerateMipSubLevels, 412 /* IDirect3DTexture9 */ 413 d3d9_texture_2d_GetLevelDesc, 414 d3d9_texture_2d_GetSurfaceLevel, 415 d3d9_texture_2d_LockRect, 416 d3d9_texture_2d_UnlockRect, 417 d3d9_texture_2d_AddDirtyRect, 418 }; 419 420 static HRESULT WINAPI d3d9_texture_cube_QueryInterface(IDirect3DCubeTexture9 *iface, REFIID riid, void **out) 421 { 422 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); 423 424 if (IsEqualGUID(riid, &IID_IDirect3DCubeTexture9) 425 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9) 426 || IsEqualGUID(riid, &IID_IDirect3DResource9) 427 || IsEqualGUID(riid, &IID_IUnknown)) 428 { 429 IDirect3DCubeTexture9_AddRef(iface); 430 *out = iface; 431 return S_OK; 432 } 433 434 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); 435 436 *out = NULL; 437 return E_NOINTERFACE; 438 } 439 440 static ULONG WINAPI d3d9_texture_cube_AddRef(IDirect3DCubeTexture9 *iface) 441 { 442 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); 443 ULONG ref = InterlockedIncrement(&texture->resource.refcount); 444 445 TRACE("%p increasing refcount to %u.\n", iface, ref); 446 447 if (ref == 1) 448 { 449 struct d3d9_surface *surface; 450 451 IDirect3DDevice9Ex_AddRef(texture->parent_device); 452 wined3d_mutex_lock(); 453 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry) 454 { 455 wined3d_rendertarget_view_decref(surface->wined3d_rtv); 456 } 457 wined3d_texture_incref(texture->wined3d_texture); 458 wined3d_mutex_unlock(); 459 } 460 461 return ref; 462 } 463 464 static ULONG WINAPI d3d9_texture_cube_Release(IDirect3DCubeTexture9 *iface) 465 { 466 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); 467 ULONG ref = InterlockedDecrement(&texture->resource.refcount); 468 469 TRACE("%p decreasing refcount to %u.\n", iface, ref); 470 471 if (!ref) 472 { 473 IDirect3DDevice9Ex *parent_device = texture->parent_device; 474 struct d3d9_surface *surface; 475 476 TRACE("Releasing child %p.\n", texture->wined3d_texture); 477 478 wined3d_mutex_lock(); 479 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry) 480 { 481 wined3d_rendertarget_view_decref(surface->wined3d_rtv); 482 } 483 wined3d_texture_decref(texture->wined3d_texture); 484 wined3d_mutex_unlock(); 485 486 /* Release the device last, as it may cause the device to be destroyed. */ 487 IDirect3DDevice9Ex_Release(parent_device); 488 } 489 return ref; 490 } 491 492 static HRESULT WINAPI d3d9_texture_cube_GetDevice(IDirect3DCubeTexture9 *iface, IDirect3DDevice9 **device) 493 { 494 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); 495 496 TRACE("iface %p, device %p.\n", iface, device); 497 498 *device = (IDirect3DDevice9 *)texture->parent_device; 499 IDirect3DDevice9_AddRef(*device); 500 501 TRACE("Returning device %p.\n", *device); 502 503 return D3D_OK; 504 } 505 506 static HRESULT WINAPI d3d9_texture_cube_SetPrivateData(IDirect3DCubeTexture9 *iface, 507 REFGUID guid, const void *data, DWORD data_size, DWORD flags) 508 { 509 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); 510 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n", 511 iface, debugstr_guid(guid), data, data_size, flags); 512 513 return d3d9_resource_set_private_data(&texture->resource, guid, data, data_size, flags); 514 } 515 516 static HRESULT WINAPI d3d9_texture_cube_GetPrivateData(IDirect3DCubeTexture9 *iface, 517 REFGUID guid, void *data, DWORD *data_size) 518 { 519 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); 520 TRACE("iface %p, guid %s, data %p, data_size %p.\n", 521 iface, debugstr_guid(guid), data, data_size); 522 523 return d3d9_resource_get_private_data(&texture->resource, guid, data, data_size); 524 } 525 526 static HRESULT WINAPI d3d9_texture_cube_FreePrivateData(IDirect3DCubeTexture9 *iface, REFGUID guid) 527 { 528 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); 529 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid)); 530 531 return d3d9_resource_free_private_data(&texture->resource, guid); 532 } 533 534 static DWORD WINAPI d3d9_texture_cube_SetPriority(IDirect3DCubeTexture9 *iface, DWORD priority) 535 { 536 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); 537 struct wined3d_resource *resource; 538 DWORD ret; 539 540 TRACE("iface %p, priority %u.\n", iface, priority); 541 542 wined3d_mutex_lock(); 543 resource = wined3d_texture_get_resource(texture->wined3d_texture); 544 ret = wined3d_resource_set_priority(resource, priority); 545 wined3d_mutex_unlock(); 546 547 return ret; 548 } 549 550 static DWORD WINAPI d3d9_texture_cube_GetPriority(IDirect3DCubeTexture9 *iface) 551 { 552 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); 553 const struct wined3d_resource *resource; 554 DWORD ret; 555 556 TRACE("iface %p.\n", iface); 557 558 wined3d_mutex_lock(); 559 resource = wined3d_texture_get_resource(texture->wined3d_texture); 560 ret = wined3d_resource_get_priority(resource); 561 wined3d_mutex_unlock(); 562 563 return ret; 564 } 565 566 static void WINAPI d3d9_texture_cube_PreLoad(IDirect3DCubeTexture9 *iface) 567 { 568 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); 569 570 TRACE("iface %p.\n", iface); 571 572 wined3d_mutex_lock(); 573 wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture)); 574 wined3d_mutex_unlock(); 575 } 576 577 static D3DRESOURCETYPE WINAPI d3d9_texture_cube_GetType(IDirect3DCubeTexture9 *iface) 578 { 579 TRACE("iface %p.\n", iface); 580 581 return D3DRTYPE_CUBETEXTURE; 582 } 583 584 static DWORD WINAPI d3d9_texture_cube_SetLOD(IDirect3DCubeTexture9 *iface, DWORD lod) 585 { 586 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); 587 DWORD ret; 588 589 TRACE("iface %p, lod %u.\n", iface, lod); 590 591 wined3d_mutex_lock(); 592 ret = wined3d_texture_set_lod(texture->wined3d_texture, lod); 593 wined3d_mutex_unlock(); 594 595 return ret; 596 } 597 598 static DWORD WINAPI d3d9_texture_cube_GetLOD(IDirect3DCubeTexture9 *iface) 599 { 600 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); 601 DWORD ret; 602 603 TRACE("iface %p.\n", iface); 604 605 wined3d_mutex_lock(); 606 ret = wined3d_texture_get_lod(texture->wined3d_texture); 607 wined3d_mutex_unlock(); 608 609 return ret; 610 } 611 612 static DWORD WINAPI d3d9_texture_cube_GetLevelCount(IDirect3DCubeTexture9 *iface) 613 { 614 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); 615 DWORD ret; 616 617 TRACE("iface %p.\n", iface); 618 619 wined3d_mutex_lock(); 620 ret = wined3d_texture_get_level_count(texture->wined3d_texture); 621 wined3d_mutex_unlock(); 622 623 return ret; 624 } 625 626 static HRESULT WINAPI d3d9_texture_cube_SetAutoGenFilterType(IDirect3DCubeTexture9 *iface, 627 D3DTEXTUREFILTERTYPE filter_type) 628 { 629 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); 630 HRESULT hr; 631 632 TRACE("iface %p, filter_type %#x.\n", iface, filter_type); 633 634 wined3d_mutex_lock(); 635 hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture, 636 (enum wined3d_texture_filter_type)filter_type); 637 wined3d_mutex_unlock(); 638 639 return hr; 640 } 641 642 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_cube_GetAutoGenFilterType(IDirect3DCubeTexture9 *iface) 643 { 644 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); 645 D3DTEXTUREFILTERTYPE ret; 646 647 TRACE("iface %p.\n", iface); 648 649 wined3d_mutex_lock(); 650 ret = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture); 651 wined3d_mutex_unlock(); 652 653 return ret; 654 } 655 656 static void WINAPI d3d9_texture_cube_GenerateMipSubLevels(IDirect3DCubeTexture9 *iface) 657 { 658 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); 659 660 TRACE("iface %p.\n", iface); 661 662 wined3d_mutex_lock(); 663 wined3d_texture_generate_mipmaps(texture->wined3d_texture); 664 wined3d_mutex_unlock(); 665 } 666 667 static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *iface, UINT level, D3DSURFACE_DESC *desc) 668 { 669 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); 670 struct wined3d_sub_resource_desc wined3d_desc; 671 DWORD level_count; 672 HRESULT hr; 673 674 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc); 675 676 wined3d_mutex_lock(); 677 level_count = wined3d_texture_get_level_count(texture->wined3d_texture); 678 if (level >= level_count) 679 { 680 wined3d_mutex_unlock(); 681 return D3DERR_INVALIDCALL; 682 } 683 684 if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc))) 685 { 686 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); 687 desc->Type = D3DRTYPE_SURFACE; 688 desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK; 689 desc->Pool = wined3d_desc.pool; 690 desc->MultiSampleType = wined3d_desc.multisample_type; 691 desc->MultiSampleQuality = wined3d_desc.multisample_quality; 692 desc->Width = wined3d_desc.width; 693 desc->Height = wined3d_desc.height; 694 } 695 wined3d_mutex_unlock(); 696 697 return hr; 698 } 699 700 static HRESULT WINAPI d3d9_texture_cube_GetCubeMapSurface(IDirect3DCubeTexture9 *iface, 701 D3DCUBEMAP_FACES face, UINT level, IDirect3DSurface9 **surface) 702 { 703 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); 704 struct d3d9_surface *surface_impl; 705 UINT sub_resource_idx; 706 DWORD level_count; 707 708 TRACE("iface %p, face %#x, level %u, surface %p.\n", iface, face, level, surface); 709 710 wined3d_mutex_lock(); 711 level_count = wined3d_texture_get_level_count(texture->wined3d_texture); 712 if (level >= level_count) 713 { 714 wined3d_mutex_unlock(); 715 return D3DERR_INVALIDCALL; 716 } 717 718 sub_resource_idx = level_count * face + level; 719 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx))) 720 { 721 wined3d_mutex_unlock(); 722 return D3DERR_INVALIDCALL; 723 } 724 725 *surface = &surface_impl->IDirect3DSurface9_iface; 726 IDirect3DSurface9_AddRef(*surface); 727 wined3d_mutex_unlock(); 728 729 return D3D_OK; 730 } 731 732 static HRESULT WINAPI d3d9_texture_cube_LockRect(IDirect3DCubeTexture9 *iface, 733 D3DCUBEMAP_FACES face, UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect, 734 DWORD flags) 735 { 736 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); 737 struct d3d9_surface *surface_impl; 738 UINT sub_resource_idx; 739 HRESULT hr; 740 741 TRACE("iface %p, face %#x, level %u, locked_rect %p, rect %p, flags %#x.\n", 742 iface, face, level, locked_rect, rect, flags); 743 744 wined3d_mutex_lock(); 745 sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level; 746 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx))) 747 hr = D3DERR_INVALIDCALL; 748 else 749 hr = IDirect3DSurface9_LockRect(&surface_impl->IDirect3DSurface9_iface, locked_rect, rect, flags); 750 wined3d_mutex_unlock(); 751 752 return hr; 753 } 754 755 static HRESULT WINAPI d3d9_texture_cube_UnlockRect(IDirect3DCubeTexture9 *iface, 756 D3DCUBEMAP_FACES face, UINT level) 757 { 758 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); 759 struct d3d9_surface *surface_impl; 760 UINT sub_resource_idx; 761 HRESULT hr; 762 763 TRACE("iface %p, face %#x, level %u.\n", iface, face, level); 764 765 wined3d_mutex_lock(); 766 sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level; 767 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx))) 768 hr = D3DERR_INVALIDCALL; 769 else 770 hr = IDirect3DSurface9_UnlockRect(&surface_impl->IDirect3DSurface9_iface); 771 wined3d_mutex_unlock(); 772 773 return hr; 774 } 775 776 static HRESULT WINAPI d3d9_texture_cube_AddDirtyRect(IDirect3DCubeTexture9 *iface, 777 D3DCUBEMAP_FACES face, const RECT *dirty_rect) 778 { 779 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); 780 HRESULT hr; 781 782 TRACE("iface %p, face %#x, dirty_rect %s.\n", 783 iface, face, wine_dbgstr_rect(dirty_rect)); 784 785 wined3d_mutex_lock(); 786 if (!dirty_rect) 787 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, NULL); 788 else 789 { 790 struct wined3d_box dirty_region; 791 792 wined3d_box_set(&dirty_region, dirty_rect->left, dirty_rect->top, dirty_rect->right, dirty_rect->bottom, 0, 1); 793 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, &dirty_region); 794 } 795 wined3d_mutex_unlock(); 796 797 return hr; 798 } 799 800 static const IDirect3DCubeTexture9Vtbl d3d9_texture_cube_vtbl = 801 { 802 /* IUnknown */ 803 d3d9_texture_cube_QueryInterface, 804 d3d9_texture_cube_AddRef, 805 d3d9_texture_cube_Release, 806 /* IDirect3DResource9 */ 807 d3d9_texture_cube_GetDevice, 808 d3d9_texture_cube_SetPrivateData, 809 d3d9_texture_cube_GetPrivateData, 810 d3d9_texture_cube_FreePrivateData, 811 d3d9_texture_cube_SetPriority, 812 d3d9_texture_cube_GetPriority, 813 d3d9_texture_cube_PreLoad, 814 d3d9_texture_cube_GetType, 815 /* IDirect3DBaseTexture9 */ 816 d3d9_texture_cube_SetLOD, 817 d3d9_texture_cube_GetLOD, 818 d3d9_texture_cube_GetLevelCount, 819 d3d9_texture_cube_SetAutoGenFilterType, 820 d3d9_texture_cube_GetAutoGenFilterType, 821 d3d9_texture_cube_GenerateMipSubLevels, 822 /* IDirect3DCubeTexture9 */ 823 d3d9_texture_cube_GetLevelDesc, 824 d3d9_texture_cube_GetCubeMapSurface, 825 d3d9_texture_cube_LockRect, 826 d3d9_texture_cube_UnlockRect, 827 d3d9_texture_cube_AddDirtyRect, 828 }; 829 830 static HRESULT WINAPI d3d9_texture_3d_QueryInterface(IDirect3DVolumeTexture9 *iface, REFIID riid, void **out) 831 { 832 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); 833 834 if (IsEqualGUID(riid, &IID_IDirect3DVolumeTexture9) 835 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9) 836 || IsEqualGUID(riid, &IID_IDirect3DResource9) 837 || IsEqualGUID(riid, &IID_IUnknown)) 838 { 839 IDirect3DVolumeTexture9_AddRef(iface); 840 *out = iface; 841 return S_OK; 842 } 843 844 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); 845 846 *out = NULL; 847 return E_NOINTERFACE; 848 } 849 850 static ULONG WINAPI d3d9_texture_3d_AddRef(IDirect3DVolumeTexture9 *iface) 851 { 852 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); 853 ULONG ref = InterlockedIncrement(&texture->resource.refcount); 854 855 TRACE("%p increasing refcount to %u.\n", iface, ref); 856 857 if (ref == 1) 858 { 859 IDirect3DDevice9Ex_AddRef(texture->parent_device); 860 wined3d_mutex_lock(); 861 wined3d_texture_incref(texture->wined3d_texture); 862 wined3d_mutex_unlock(); 863 } 864 865 return ref; 866 } 867 868 static ULONG WINAPI d3d9_texture_3d_Release(IDirect3DVolumeTexture9 *iface) 869 { 870 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); 871 ULONG ref = InterlockedDecrement(&texture->resource.refcount); 872 873 TRACE("%p decreasing refcount to %u.\n", iface, ref); 874 875 if (!ref) 876 { 877 IDirect3DDevice9Ex *parent_device = texture->parent_device; 878 879 wined3d_mutex_lock(); 880 wined3d_texture_decref(texture->wined3d_texture); 881 wined3d_mutex_unlock(); 882 883 /* Release the device last, as it may cause the device to be destroyed. */ 884 IDirect3DDevice9Ex_Release(parent_device); 885 } 886 return ref; 887 } 888 889 static HRESULT WINAPI d3d9_texture_3d_GetDevice(IDirect3DVolumeTexture9 *iface, IDirect3DDevice9 **device) 890 { 891 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); 892 893 TRACE("iface %p, device %p.\n", iface, device); 894 895 *device = (IDirect3DDevice9 *)texture->parent_device; 896 IDirect3DDevice9_AddRef(*device); 897 898 TRACE("Returning device %p.\n", *device); 899 900 return D3D_OK; 901 } 902 903 static HRESULT WINAPI d3d9_texture_3d_SetPrivateData(IDirect3DVolumeTexture9 *iface, 904 REFGUID guid, const void *data, DWORD data_size, DWORD flags) 905 { 906 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); 907 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n", 908 iface, debugstr_guid(guid), data, data_size, flags); 909 910 return d3d9_resource_set_private_data(&texture->resource, guid, data, data_size, flags); 911 } 912 913 static HRESULT WINAPI d3d9_texture_3d_GetPrivateData(IDirect3DVolumeTexture9 *iface, 914 REFGUID guid, void *data, DWORD *data_size) 915 { 916 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); 917 TRACE("iface %p, guid %s, data %p, data_size %p.\n", 918 iface, debugstr_guid(guid), data, data_size); 919 920 return d3d9_resource_get_private_data(&texture->resource, guid, data, data_size); 921 } 922 923 static HRESULT WINAPI d3d9_texture_3d_FreePrivateData(IDirect3DVolumeTexture9 *iface, REFGUID guid) 924 { 925 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); 926 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid)); 927 928 return d3d9_resource_free_private_data(&texture->resource, guid); 929 } 930 931 static DWORD WINAPI d3d9_texture_3d_SetPriority(IDirect3DVolumeTexture9 *iface, DWORD priority) 932 { 933 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); 934 struct wined3d_resource *resource; 935 DWORD ret; 936 937 TRACE("iface %p, priority %u.\n", iface, priority); 938 939 wined3d_mutex_lock(); 940 resource = wined3d_texture_get_resource(texture->wined3d_texture); 941 ret = wined3d_resource_set_priority(resource, priority); 942 wined3d_mutex_unlock(); 943 944 return ret; 945 } 946 947 static DWORD WINAPI d3d9_texture_3d_GetPriority(IDirect3DVolumeTexture9 *iface) 948 { 949 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); 950 const struct wined3d_resource *resource; 951 DWORD ret; 952 953 TRACE("iface %p.\n", iface); 954 955 wined3d_mutex_lock(); 956 resource = wined3d_texture_get_resource(texture->wined3d_texture); 957 ret = wined3d_resource_get_priority(resource); 958 wined3d_mutex_unlock(); 959 960 return ret; 961 } 962 963 static void WINAPI d3d9_texture_3d_PreLoad(IDirect3DVolumeTexture9 *iface) 964 { 965 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); 966 967 TRACE("iface %p.\n", iface); 968 969 wined3d_mutex_lock(); 970 wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture)); 971 wined3d_mutex_unlock(); 972 } 973 974 static D3DRESOURCETYPE WINAPI d3d9_texture_3d_GetType(IDirect3DVolumeTexture9 *iface) 975 { 976 TRACE("iface %p.\n", iface); 977 978 return D3DRTYPE_VOLUMETEXTURE; 979 } 980 981 static DWORD WINAPI d3d9_texture_3d_SetLOD(IDirect3DVolumeTexture9 *iface, DWORD lod) 982 { 983 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); 984 DWORD ret; 985 986 TRACE("iface %p, lod %u.\n", iface, lod); 987 988 wined3d_mutex_lock(); 989 ret = wined3d_texture_set_lod(texture->wined3d_texture, lod); 990 wined3d_mutex_unlock(); 991 992 return ret; 993 } 994 995 static DWORD WINAPI d3d9_texture_3d_GetLOD(IDirect3DVolumeTexture9 *iface) 996 { 997 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); 998 DWORD ret; 999 1000 TRACE("iface %p.\n", iface); 1001 1002 wined3d_mutex_lock(); 1003 ret = wined3d_texture_get_lod(texture->wined3d_texture); 1004 wined3d_mutex_unlock(); 1005 1006 return ret; 1007 } 1008 1009 static DWORD WINAPI d3d9_texture_3d_GetLevelCount(IDirect3DVolumeTexture9 *iface) 1010 { 1011 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); 1012 DWORD ret; 1013 1014 TRACE("iface %p.\n", iface); 1015 1016 wined3d_mutex_lock(); 1017 ret = wined3d_texture_get_level_count(texture->wined3d_texture); 1018 wined3d_mutex_unlock(); 1019 1020 return ret; 1021 } 1022 1023 static HRESULT WINAPI d3d9_texture_3d_SetAutoGenFilterType(IDirect3DVolumeTexture9 *iface, 1024 D3DTEXTUREFILTERTYPE filter_type) 1025 { 1026 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); 1027 HRESULT hr; 1028 1029 TRACE("iface %p, filter_type %#x.\n", iface, filter_type); 1030 1031 wined3d_mutex_lock(); 1032 hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture, 1033 (enum wined3d_texture_filter_type)filter_type); 1034 wined3d_mutex_unlock(); 1035 1036 return hr; 1037 } 1038 1039 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_3d_GetAutoGenFilterType(IDirect3DVolumeTexture9 *iface) 1040 { 1041 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); 1042 D3DTEXTUREFILTERTYPE filter_type; 1043 1044 TRACE("iface %p.\n", iface); 1045 1046 wined3d_mutex_lock(); 1047 filter_type = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture); 1048 wined3d_mutex_unlock(); 1049 1050 return filter_type; 1051 } 1052 1053 static void WINAPI d3d9_texture_3d_GenerateMipSubLevels(IDirect3DVolumeTexture9 *iface) 1054 { 1055 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); 1056 1057 TRACE("iface %p.\n", iface); 1058 1059 wined3d_mutex_lock(); 1060 wined3d_texture_generate_mipmaps(texture->wined3d_texture); 1061 wined3d_mutex_unlock(); 1062 } 1063 1064 static HRESULT WINAPI d3d9_texture_3d_GetLevelDesc(IDirect3DVolumeTexture9 *iface, UINT level, D3DVOLUME_DESC *desc) 1065 { 1066 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); 1067 struct wined3d_sub_resource_desc wined3d_desc; 1068 HRESULT hr; 1069 1070 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc); 1071 1072 wined3d_mutex_lock(); 1073 if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc))) 1074 { 1075 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); 1076 desc->Type = D3DRTYPE_VOLUME; 1077 desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK; 1078 desc->Pool = wined3d_desc.pool; 1079 desc->Width = wined3d_desc.width; 1080 desc->Height = wined3d_desc.height; 1081 desc->Depth = wined3d_desc.depth; 1082 } 1083 wined3d_mutex_unlock(); 1084 1085 return hr; 1086 } 1087 1088 static HRESULT WINAPI d3d9_texture_3d_GetVolumeLevel(IDirect3DVolumeTexture9 *iface, 1089 UINT level, IDirect3DVolume9 **volume) 1090 { 1091 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); 1092 struct d3d9_volume *volume_impl; 1093 1094 TRACE("iface %p, level %u, volume %p.\n", iface, level, volume); 1095 1096 wined3d_mutex_lock(); 1097 if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) 1098 { 1099 wined3d_mutex_unlock(); 1100 return D3DERR_INVALIDCALL; 1101 } 1102 1103 *volume = &volume_impl->IDirect3DVolume9_iface; 1104 IDirect3DVolume9_AddRef(*volume); 1105 wined3d_mutex_unlock(); 1106 1107 return D3D_OK; 1108 } 1109 1110 static HRESULT WINAPI d3d9_texture_3d_LockBox(IDirect3DVolumeTexture9 *iface, 1111 UINT level, D3DLOCKED_BOX *locked_box, const D3DBOX *box, DWORD flags) 1112 { 1113 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); 1114 struct d3d9_volume *volume_impl; 1115 HRESULT hr; 1116 1117 TRACE("iface %p, level %u, locked_box %p, box %p, flags %#x.\n", 1118 iface, level, locked_box, box, flags); 1119 1120 wined3d_mutex_lock(); 1121 if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) 1122 hr = D3DERR_INVALIDCALL; 1123 else 1124 hr = IDirect3DVolume9_LockBox(&volume_impl->IDirect3DVolume9_iface, locked_box, box, flags); 1125 wined3d_mutex_unlock(); 1126 1127 return hr; 1128 } 1129 1130 static HRESULT WINAPI d3d9_texture_3d_UnlockBox(IDirect3DVolumeTexture9 *iface, UINT level) 1131 { 1132 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); 1133 struct d3d9_volume *volume_impl; 1134 HRESULT hr; 1135 1136 TRACE("iface %p, level %u.\n", iface, level); 1137 1138 wined3d_mutex_lock(); 1139 if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) 1140 hr = D3DERR_INVALIDCALL; 1141 else 1142 hr = IDirect3DVolume9_UnlockBox(&volume_impl->IDirect3DVolume9_iface); 1143 wined3d_mutex_unlock(); 1144 1145 return hr; 1146 } 1147 1148 static HRESULT WINAPI d3d9_texture_3d_AddDirtyBox(IDirect3DVolumeTexture9 *iface, const D3DBOX *dirty_box) 1149 { 1150 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); 1151 HRESULT hr; 1152 1153 TRACE("iface %p, dirty_box %p.\n", iface, dirty_box); 1154 1155 wined3d_mutex_lock(); 1156 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, (const struct wined3d_box *)dirty_box); 1157 wined3d_mutex_unlock(); 1158 1159 return hr; 1160 } 1161 1162 1163 static const IDirect3DVolumeTexture9Vtbl d3d9_texture_3d_vtbl = 1164 { 1165 /* IUnknown */ 1166 d3d9_texture_3d_QueryInterface, 1167 d3d9_texture_3d_AddRef, 1168 d3d9_texture_3d_Release, 1169 /* IDirect3DResource9 */ 1170 d3d9_texture_3d_GetDevice, 1171 d3d9_texture_3d_SetPrivateData, 1172 d3d9_texture_3d_GetPrivateData, 1173 d3d9_texture_3d_FreePrivateData, 1174 d3d9_texture_3d_SetPriority, 1175 d3d9_texture_3d_GetPriority, 1176 d3d9_texture_3d_PreLoad, 1177 d3d9_texture_3d_GetType, 1178 /* IDirect3DBaseTexture9 */ 1179 d3d9_texture_3d_SetLOD, 1180 d3d9_texture_3d_GetLOD, 1181 d3d9_texture_3d_GetLevelCount, 1182 d3d9_texture_3d_SetAutoGenFilterType, 1183 d3d9_texture_3d_GetAutoGenFilterType, 1184 d3d9_texture_3d_GenerateMipSubLevels, 1185 /* IDirect3DVolumeTexture9 */ 1186 d3d9_texture_3d_GetLevelDesc, 1187 d3d9_texture_3d_GetVolumeLevel, 1188 d3d9_texture_3d_LockBox, 1189 d3d9_texture_3d_UnlockBox, 1190 d3d9_texture_3d_AddDirtyBox, 1191 }; 1192 1193 struct d3d9_texture *unsafe_impl_from_IDirect3DBaseTexture9(IDirect3DBaseTexture9 *iface) 1194 { 1195 if (!iface) 1196 return NULL; 1197 1198 if (iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl 1199 && iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl 1200 && iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl) 1201 { 1202 WARN("%p is not a valid IDirect3DBaseTexture9 interface.\n", iface); 1203 return NULL; 1204 } 1205 1206 return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface); 1207 } 1208 1209 static void STDMETHODCALLTYPE d3d9_texture_wined3d_object_destroyed(void *parent) 1210 { 1211 struct d3d9_texture *texture = parent; 1212 d3d9_resource_cleanup(&texture->resource); 1213 HeapFree(GetProcessHeap(), 0, texture); 1214 } 1215 1216 static const struct wined3d_parent_ops d3d9_texture_wined3d_parent_ops = 1217 { 1218 d3d9_texture_wined3d_object_destroyed, 1219 }; 1220 1221 HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device, 1222 UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool) 1223 { 1224 struct wined3d_resource_desc desc; 1225 DWORD flags = 0; 1226 HRESULT hr; 1227 1228 texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl; 1229 d3d9_resource_init(&texture->resource); 1230 list_init(&texture->rtv_list); 1231 1232 desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; 1233 desc.format = wined3dformat_from_d3dformat(format); 1234 desc.multisample_type = WINED3D_MULTISAMPLE_NONE; 1235 desc.multisample_quality = 0; 1236 desc.usage = usage & WINED3DUSAGE_MASK; 1237 desc.usage |= WINED3DUSAGE_TEXTURE; 1238 desc.pool = pool; 1239 desc.width = width; 1240 desc.height = height; 1241 desc.depth = 1; 1242 desc.size = 0; 1243 1244 if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC)) 1245 flags |= WINED3D_TEXTURE_CREATE_MAPPABLE; 1246 1247 if (is_gdi_compat_wined3dformat(desc.format)) 1248 flags |= WINED3D_TEXTURE_CREATE_GET_DC; 1249 1250 if (!levels) 1251 { 1252 if (usage & D3DUSAGE_AUTOGENMIPMAP) 1253 levels = 1; 1254 else 1255 levels = wined3d_log2i(max(width, height)) + 1; 1256 } 1257 1258 wined3d_mutex_lock(); 1259 hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, flags, 1260 NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture); 1261 wined3d_mutex_unlock(); 1262 if (FAILED(hr)) 1263 { 1264 WARN("Failed to create wined3d texture, hr %#x.\n", hr); 1265 return hr; 1266 } 1267 1268 texture->parent_device = &device->IDirect3DDevice9Ex_iface; 1269 IDirect3DDevice9Ex_AddRef(texture->parent_device); 1270 1271 return D3D_OK; 1272 } 1273 1274 HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *device, 1275 UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool) 1276 { 1277 struct wined3d_resource_desc desc; 1278 DWORD flags = 0; 1279 HRESULT hr; 1280 1281 texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl; 1282 d3d9_resource_init(&texture->resource); 1283 list_init(&texture->rtv_list); 1284 1285 desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; 1286 desc.format = wined3dformat_from_d3dformat(format); 1287 desc.multisample_type = WINED3D_MULTISAMPLE_NONE; 1288 desc.multisample_quality = 0; 1289 desc.usage = usage & WINED3DUSAGE_MASK; 1290 desc.usage |= WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_TEXTURE; 1291 desc.pool = pool; 1292 desc.width = edge_length; 1293 desc.height = edge_length; 1294 desc.depth = 1; 1295 desc.size = 0; 1296 1297 if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC)) 1298 flags |= WINED3D_TEXTURE_CREATE_MAPPABLE; 1299 1300 if (is_gdi_compat_wined3dformat(desc.format)) 1301 flags |= WINED3D_TEXTURE_CREATE_GET_DC; 1302 1303 if (!levels) 1304 { 1305 if (usage & D3DUSAGE_AUTOGENMIPMAP) 1306 levels = 1; 1307 else 1308 levels = wined3d_log2i(edge_length) + 1; 1309 } 1310 1311 wined3d_mutex_lock(); 1312 hr = wined3d_texture_create(device->wined3d_device, &desc, 6, levels, flags, 1313 NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture); 1314 wined3d_mutex_unlock(); 1315 if (FAILED(hr)) 1316 { 1317 WARN("Failed to create wined3d cube texture, hr %#x.\n", hr); 1318 return hr; 1319 } 1320 1321 texture->parent_device = &device->IDirect3DDevice9Ex_iface; 1322 IDirect3DDevice9Ex_AddRef(texture->parent_device); 1323 1324 return D3D_OK; 1325 } 1326 1327 HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *device, 1328 UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool) 1329 { 1330 struct wined3d_resource_desc desc; 1331 HRESULT hr; 1332 1333 texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl; 1334 d3d9_resource_init(&texture->resource); 1335 list_init(&texture->rtv_list); 1336 1337 desc.resource_type = WINED3D_RTYPE_TEXTURE_3D; 1338 desc.format = wined3dformat_from_d3dformat(format); 1339 desc.multisample_type = WINED3D_MULTISAMPLE_NONE; 1340 desc.multisample_quality = 0; 1341 desc.usage = usage & WINED3DUSAGE_MASK; 1342 desc.usage |= WINED3DUSAGE_TEXTURE; 1343 desc.pool = pool; 1344 desc.width = width; 1345 desc.height = height; 1346 desc.depth = depth; 1347 desc.size = 0; 1348 1349 if (!levels) 1350 { 1351 if (usage & D3DUSAGE_AUTOGENMIPMAP) 1352 levels = 1; 1353 else 1354 levels = wined3d_log2i(max(max(width, height), depth)) + 1; 1355 } 1356 1357 wined3d_mutex_lock(); 1358 hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, 0, 1359 NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture); 1360 wined3d_mutex_unlock(); 1361 if (FAILED(hr)) 1362 { 1363 WARN("Failed to create wined3d volume texture, hr %#x.\n", hr); 1364 return hr; 1365 } 1366 1367 texture->parent_device = &device->IDirect3DDevice9Ex_iface; 1368 IDirect3DDevice9Ex_AddRef(texture->parent_device); 1369 1370 return D3D_OK; 1371 } 1372