1/* 2 * Copyright 2011 Joakim Sindholt <opensource@zhasha.com> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * on the rights to use, copy, modify, merge, publish, distribute, sub 8 * license, and/or sell copies of the Software, and to permit persons to whom 9 * the Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 22 23#include "basetexture9.h" 24#include "device9.h" 25 26/* For UploadSelf: */ 27#include "texture9.h" 28#include "cubetexture9.h" 29#include "volumetexture9.h" 30#include "nine_pipe.h" 31 32#if defined(DEBUG) || !defined(NDEBUG) 33#include "nine_dump.h" 34#endif 35 36#include "util/format/u_format.h" 37 38#define DBG_CHANNEL DBG_BASETEXTURE 39 40HRESULT 41NineBaseTexture9_ctor( struct NineBaseTexture9 *This, 42 struct NineUnknownParams *pParams, 43 struct pipe_resource *initResource, 44 D3DRESOURCETYPE Type, 45 D3DFORMAT format, 46 D3DPOOL Pool, 47 DWORD Usage) 48{ 49 BOOL alloc = (Pool == D3DPOOL_DEFAULT) && !initResource && 50 (format != D3DFMT_NULL); 51 HRESULT hr; 52 53 DBG("This=%p, pParams=%p initResource=%p Type=%d format=%d Pool=%d Usage=%d\n", 54 This, pParams, initResource, Type, format, Pool, Usage); 55 56 user_assert(!(Usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) || 57 Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); 58 user_assert(!(Usage & D3DUSAGE_DYNAMIC) || 59 !(Pool == D3DPOOL_MANAGED || 60 Pool == D3DPOOL_SCRATCH), D3DERR_INVALIDCALL); 61 62 hr = NineResource9_ctor(&This->base, pParams, initResource, alloc, Type, Pool, Usage); 63 if (FAILED(hr)) 64 return hr; 65 66 This->format = format; 67 This->mipfilter = (Usage & D3DUSAGE_AUTOGENMIPMAP) ? 68 D3DTEXF_LINEAR : D3DTEXF_NONE; 69 /* In the case of D3DUSAGE_AUTOGENMIPMAP, only the first level is accessible, 70 * and thus needs a surface created. */ 71 This->level_count = (Usage & D3DUSAGE_AUTOGENMIPMAP) ? 1 : (This->base.info.last_level+1); 72 This->managed.lod = 0; 73 This->managed.lod_resident = -1; 74 /* Mark the texture as dirty to trigger first upload when we need the texture, 75 * even if it wasn't set by the application */ 76 if (Pool == D3DPOOL_MANAGED) 77 This->managed.dirty = TRUE; 78 /* When a depth buffer is sampled, it is for shadow mapping, except for 79 * D3DFMT_INTZ, D3DFMT_DF16 and D3DFMT_DF24. 80 * In addition D3DFMT_INTZ can be used for both texturing and depth buffering 81 * if z write is disabled. This particular feature may not work for us in 82 * practice because OGL doesn't have that. However apparently it is known 83 * some cards have performance issues with this feature, so real apps 84 * shouldn't use it. */ 85 This->shadow = (This->format != D3DFMT_INTZ && This->format != D3DFMT_DF16 && 86 This->format != D3DFMT_DF24) && 87 util_format_has_depth(util_format_description(This->base.info.format)); 88 This->fetch4_compatible = fetch4_compatible_format(This->format); 89 90 list_inithead(&This->list); 91 list_inithead(&This->list2); 92 if (Pool == D3DPOOL_MANAGED) 93 list_add(&This->list2, &This->base.base.device->managed_textures); 94 95 return D3D_OK; 96} 97 98void 99NineBaseTexture9_dtor( struct NineBaseTexture9 *This ) 100{ 101 DBG("This=%p\n", This); 102 103 pipe_sampler_view_reference(&This->view[0], NULL); 104 pipe_sampler_view_reference(&This->view[1], NULL); 105 106 if (list_is_linked(&This->list)) 107 list_del(&This->list); 108 if (list_is_linked(&This->list2)) 109 list_del(&This->list2); 110 111 NineResource9_dtor(&This->base); 112} 113 114DWORD NINE_WINAPI 115NineBaseTexture9_SetLOD( struct NineBaseTexture9 *This, 116 DWORD LODNew ) 117{ 118 DWORD old = This->managed.lod; 119 120 DBG("This=%p LODNew=%d\n", This, LODNew); 121 122 user_assert(This->base.pool == D3DPOOL_MANAGED, 0); 123 124 This->managed.lod = MIN2(LODNew, This->level_count-1); 125 126 if (This->managed.lod != old && This->bind_count && list_is_empty(&This->list)) 127 list_add(&This->list, &This->base.base.device->update_textures); 128 129 return old; 130} 131 132DWORD NINE_WINAPI 133NineBaseTexture9_GetLOD( struct NineBaseTexture9 *This ) 134{ 135 DBG("This=%p\n", This); 136 137 return This->managed.lod; 138} 139 140DWORD NINE_WINAPI 141NineBaseTexture9_GetLevelCount( struct NineBaseTexture9 *This ) 142{ 143 DBG("This=%p\n", This); 144 145 return This->level_count; 146} 147 148HRESULT NINE_WINAPI 149NineBaseTexture9_SetAutoGenFilterType( struct NineBaseTexture9 *This, 150 D3DTEXTUREFILTERTYPE FilterType ) 151{ 152 DBG("This=%p FilterType=%d\n", This, FilterType); 153 154 if (!(This->base.usage & D3DUSAGE_AUTOGENMIPMAP)) 155 return D3D_OK; 156 user_assert(FilterType != D3DTEXF_NONE, D3DERR_INVALIDCALL); 157 158 This->mipfilter = FilterType; 159 This->dirty_mip = TRUE; 160 NineBaseTexture9_GenerateMipSubLevels(This); 161 162 return D3D_OK; 163} 164 165D3DTEXTUREFILTERTYPE NINE_WINAPI 166NineBaseTexture9_GetAutoGenFilterType( struct NineBaseTexture9 *This ) 167{ 168 DBG("This=%p\n", This); 169 170 return This->mipfilter; 171} 172 173HRESULT 174NineBaseTexture9_UploadSelf( struct NineBaseTexture9 *This ) 175{ 176 HRESULT hr; 177 unsigned l, min_level_dirty = This->managed.lod; 178 BOOL update_lod; 179 180 DBG("This=%p dirty=%i type=%s\n", This, This->managed.dirty, 181 nine_D3DRTYPE_to_str(This->base.type)); 182 183 assert(This->base.pool == D3DPOOL_MANAGED); 184 185 update_lod = This->managed.lod_resident != This->managed.lod; 186 if (!update_lod && !This->managed.dirty) 187 return D3D_OK; 188 189 /* Allocate a new resource with the correct number of levels, 190 * Mark states for update, and tell the nine surfaces/volumes 191 * their new resource. */ 192 if (update_lod) { 193 struct pipe_resource *res; 194 195 DBG("updating LOD from %u to %u ...\n", This->managed.lod_resident, This->managed.lod); 196 197 pipe_sampler_view_reference(&This->view[0], NULL); 198 pipe_sampler_view_reference(&This->view[1], NULL); 199 200 /* Allocate a new resource */ 201 hr = NineBaseTexture9_CreatePipeResource(This, This->managed.lod_resident != -1); 202 if (FAILED(hr)) 203 return hr; 204 res = This->base.resource; 205 206 if (This->managed.lod_resident == -1) {/* no levels were resident */ 207 This->managed.dirty = FALSE; /* We are going to upload everything. */ 208 This->managed.lod_resident = This->level_count; 209 } 210 211 if (This->base.type == D3DRTYPE_TEXTURE) { 212 struct NineTexture9 *tex = NineTexture9(This); 213 214 /* last content (if apply) has been copied to the new resource. 215 * Note: We cannot render to surfaces of managed textures. 216 * Note2: the level argument passed is to get the level offset 217 * right when the texture is uploaded (the texture first level 218 * corresponds to This->managed.lod). 219 * Note3: We don't care about the value passed for the surfaces 220 * before This->managed.lod, negative with this implementation. */ 221 for (l = 0; l < This->level_count; ++l) 222 NineSurface9_SetResource(tex->surfaces[l], res, l - This->managed.lod); 223 } else 224 if (This->base.type == D3DRTYPE_CUBETEXTURE) { 225 struct NineCubeTexture9 *tex = NineCubeTexture9(This); 226 unsigned z; 227 228 for (l = 0; l < This->level_count; ++l) { 229 for (z = 0; z < 6; ++z) 230 NineSurface9_SetResource(tex->surfaces[l * 6 + z], 231 res, l - This->managed.lod); 232 } 233 } else 234 if (This->base.type == D3DRTYPE_VOLUMETEXTURE) { 235 struct NineVolumeTexture9 *tex = NineVolumeTexture9(This); 236 237 for (l = 0; l < This->level_count; ++l) 238 NineVolume9_SetResource(tex->volumes[l], res, l - This->managed.lod); 239 } else { 240 assert(!"invalid texture type"); 241 } 242 243 /* We are going to fully upload the new levels, 244 * no need to update dirty parts of the texture for these */ 245 min_level_dirty = MAX2(This->managed.lod, This->managed.lod_resident); 246 } 247 248 /* Update dirty parts of the texture */ 249 if (This->managed.dirty) { 250 if (This->base.type == D3DRTYPE_TEXTURE) { 251 struct NineTexture9 *tex = NineTexture9(This); 252 struct pipe_box box; 253 box.z = 0; 254 box.depth = 1; 255 256 DBG("TEXTURE: dirty rect=(%u,%u) (%ux%u)\n", 257 tex->dirty_rect.x, tex->dirty_rect.y, 258 tex->dirty_rect.width, tex->dirty_rect.height); 259 260 /* Note: for l < min_level_dirty, the resource is 261 * either non-existing (and thus will be entirely re-uploaded 262 * if the lod changes) or going to have a full upload */ 263 if (tex->dirty_rect.width) { 264 for (l = min_level_dirty; l < This->level_count; ++l) { 265 u_box_minify_2d(&box, &tex->dirty_rect, l); 266 NineSurface9_UploadSelf(tex->surfaces[l], &box); 267 } 268 memset(&tex->dirty_rect, 0, sizeof(tex->dirty_rect)); 269 tex->dirty_rect.depth = 1; 270 } 271 } else 272 if (This->base.type == D3DRTYPE_CUBETEXTURE) { 273 struct NineCubeTexture9 *tex = NineCubeTexture9(This); 274 unsigned z; 275 struct pipe_box box; 276 box.z = 0; 277 box.depth = 1; 278 279 for (z = 0; z < 6; ++z) { 280 DBG("FACE[%u]: dirty rect=(%u,%u) (%ux%u)\n", z, 281 tex->dirty_rect[z].x, tex->dirty_rect[z].y, 282 tex->dirty_rect[z].width, tex->dirty_rect[z].height); 283 284 if (tex->dirty_rect[z].width) { 285 for (l = min_level_dirty; l < This->level_count; ++l) { 286 u_box_minify_2d(&box, &tex->dirty_rect[z], l); 287 NineSurface9_UploadSelf(tex->surfaces[l * 6 + z], &box); 288 } 289 memset(&tex->dirty_rect[z], 0, sizeof(tex->dirty_rect[z])); 290 tex->dirty_rect[z].depth = 1; 291 } 292 } 293 } else 294 if (This->base.type == D3DRTYPE_VOLUMETEXTURE) { 295 struct NineVolumeTexture9 *tex = NineVolumeTexture9(This); 296 struct pipe_box box; 297 298 DBG("VOLUME: dirty_box=(%u,%u,%u) (%ux%ux%u)\n", 299 tex->dirty_box.x, tex->dirty_box.y, tex->dirty_box.y, 300 tex->dirty_box.width, tex->dirty_box.height, tex->dirty_box.depth); 301 302 if (tex->dirty_box.width) { 303 for (l = min_level_dirty; l < This->level_count; ++l) { 304 u_box_minify_3d(&box, &tex->dirty_box, l); 305 NineVolume9_UploadSelf(tex->volumes[l], &box); 306 } 307 memset(&tex->dirty_box, 0, sizeof(tex->dirty_box)); 308 } 309 } else { 310 assert(!"invalid texture type"); 311 } 312 This->managed.dirty = FALSE; 313 } 314 315 /* Upload the new levels */ 316 if (update_lod) { 317 if (This->base.type == D3DRTYPE_TEXTURE) { 318 struct NineTexture9 *tex = NineTexture9(This); 319 struct pipe_box box; 320 321 box.x = box.y = box.z = 0; 322 box.depth = 1; 323 for (l = This->managed.lod; l < This->managed.lod_resident; ++l) { 324 box.width = u_minify(This->base.info.width0, l); 325 box.height = u_minify(This->base.info.height0, l); 326 NineSurface9_UploadSelf(tex->surfaces[l], &box); 327 } 328 } else 329 if (This->base.type == D3DRTYPE_CUBETEXTURE) { 330 struct NineCubeTexture9 *tex = NineCubeTexture9(This); 331 struct pipe_box box; 332 unsigned z; 333 334 box.x = box.y = box.z = 0; 335 box.depth = 1; 336 for (l = This->managed.lod; l < This->managed.lod_resident; ++l) { 337 box.width = u_minify(This->base.info.width0, l); 338 box.height = u_minify(This->base.info.height0, l); 339 for (z = 0; z < 6; ++z) 340 NineSurface9_UploadSelf(tex->surfaces[l * 6 + z], &box); 341 } 342 } else 343 if (This->base.type == D3DRTYPE_VOLUMETEXTURE) { 344 struct NineVolumeTexture9 *tex = NineVolumeTexture9(This); 345 struct pipe_box box; 346 347 box.x = box.y = box.z = 0; 348 for (l = This->managed.lod; l < This->managed.lod_resident; ++l) { 349 box.width = u_minify(This->base.info.width0, l); 350 box.height = u_minify(This->base.info.height0, l); 351 box.depth = u_minify(This->base.info.depth0, l); 352 NineVolume9_UploadSelf(tex->volumes[l], &box); 353 } 354 } else { 355 assert(!"invalid texture type"); 356 } 357 358 This->managed.lod_resident = This->managed.lod; 359 } 360 361 if (This->base.usage & D3DUSAGE_AUTOGENMIPMAP) 362 This->dirty_mip = TRUE; 363 364 /* Set again the textures currently bound to update the texture data */ 365 if (This->bind_count) { 366 struct nine_state *state = &This->base.base.device->state; 367 unsigned s; 368 for (s = 0; s < NINE_MAX_SAMPLERS; ++s) 369 /* Dirty tracking is done in device9 state, not nine_context. */ 370 if (state->texture[s] == This) 371 nine_context_set_texture(This->base.base.device, s, This); 372 } 373 374 DBG("DONE, generate mip maps = %i\n", This->dirty_mip); 375 return D3D_OK; 376} 377 378void NINE_WINAPI 379NineBaseTexture9_GenerateMipSubLevels( struct NineBaseTexture9 *This ) 380{ 381 unsigned base_level = 0; 382 unsigned last_level = This->base.info.last_level - This->managed.lod; 383 unsigned first_layer = 0; 384 unsigned last_layer; 385 unsigned filter = This->mipfilter == D3DTEXF_POINT ? PIPE_TEX_FILTER_NEAREST 386 : PIPE_TEX_FILTER_LINEAR; 387 DBG("This=%p\n", This); 388 389 if (This->base.pool == D3DPOOL_MANAGED) 390 NineBaseTexture9_UploadSelf(This); 391 if (!This->dirty_mip) 392 return; 393 if (This->managed.lod) { 394 ERR("AUTOGENMIPMAP if level 0 is not resident not supported yet !\n"); 395 return; 396 } 397 398 if (!This->view[0]) 399 NineBaseTexture9_UpdateSamplerView(This, 0); 400 401 last_layer = util_max_layer(This->view[0]->texture, base_level); 402 403 nine_context_gen_mipmap(This->base.base.device, (struct NineUnknown *)This, 404 This->base.resource, 405 base_level, last_level, 406 first_layer, last_layer, filter); 407 408 This->dirty_mip = FALSE; 409} 410 411HRESULT 412NineBaseTexture9_CreatePipeResource( struct NineBaseTexture9 *This, 413 BOOL CopyData ) 414{ 415 struct pipe_context *pipe; 416 struct pipe_screen *screen = This->base.info.screen; 417 struct pipe_resource templ; 418 unsigned l, m; 419 struct pipe_resource *res; 420 struct pipe_resource *old = This->base.resource; 421 422 DBG("This=%p lod=%u last_level=%u\n", This, 423 This->managed.lod, This->base.info.last_level); 424 425 assert(This->base.pool == D3DPOOL_MANAGED); 426 427 templ = This->base.info; 428 429 if (This->managed.lod) { 430 templ.width0 = u_minify(templ.width0, This->managed.lod); 431 templ.height0 = u_minify(templ.height0, This->managed.lod); 432 templ.depth0 = u_minify(templ.depth0, This->managed.lod); 433 } 434 templ.last_level = This->base.info.last_level - This->managed.lod; 435 436 if (old) { 437 /* LOD might have changed. */ 438 if (old->width0 == templ.width0 && 439 old->height0 == templ.height0 && 440 old->depth0 == templ.depth0) 441 return D3D_OK; 442 } 443 444 res = nine_resource_create_with_retry(This->base.base.device, screen, &templ); 445 if (!res) 446 return D3DERR_OUTOFVIDEOMEMORY; 447 This->base.resource = res; 448 449 if (old && CopyData) { /* Don't return without releasing old ! */ 450 struct pipe_box box; 451 box.x = 0; 452 box.y = 0; 453 box.z = 0; 454 455 l = (This->managed.lod < This->managed.lod_resident) ? This->managed.lod_resident - This->managed.lod : 0; 456 m = (This->managed.lod < This->managed.lod_resident) ? 0 : This->managed.lod - This->managed.lod_resident; 457 458 box.width = u_minify(templ.width0, l); 459 box.height = u_minify(templ.height0, l); 460 box.depth = u_minify(templ.depth0, l); 461 462 pipe = nine_context_get_pipe_acquire(This->base.base.device); 463 464 for (; l <= templ.last_level; ++l, ++m) { 465 pipe->resource_copy_region(pipe, 466 res, l, 0, 0, 0, 467 old, m, &box); 468 box.width = u_minify(box.width, 1); 469 box.height = u_minify(box.height, 1); 470 box.depth = u_minify(box.depth, 1); 471 } 472 473 nine_context_get_pipe_release(This->base.base.device); 474 } 475 pipe_resource_reference(&old, NULL); 476 477 return D3D_OK; 478} 479 480#define SWIZZLE_TO_REPLACE(s) (s == PIPE_SWIZZLE_0 || \ 481 s == PIPE_SWIZZLE_1 || \ 482 s == PIPE_SWIZZLE_NONE) 483 484HRESULT 485NineBaseTexture9_UpdateSamplerView( struct NineBaseTexture9 *This, 486 const int sRGB ) 487{ 488 const struct util_format_description *desc; 489 struct pipe_context *pipe; 490 struct pipe_screen *screen = NineDevice9_GetScreen(This->base.base.device); 491 struct pipe_resource *resource = This->base.resource; 492 struct pipe_sampler_view templ; 493 enum pipe_format srgb_format; 494 unsigned i; 495 uint8_t swizzle[4]; 496 497 DBG("This=%p sRGB=%d\n", This, sRGB); 498 499 if (unlikely(!resource)) { 500 if (unlikely(This->format == D3DFMT_NULL)) 501 return D3D_OK; 502 NineBaseTexture9_Dump(This); 503 } 504 assert(resource); 505 506 pipe_sampler_view_reference(&This->view[sRGB], NULL); 507 508 swizzle[0] = PIPE_SWIZZLE_X; 509 swizzle[1] = PIPE_SWIZZLE_Y; 510 swizzle[2] = PIPE_SWIZZLE_Z; 511 swizzle[3] = PIPE_SWIZZLE_W; 512 desc = util_format_description(resource->format); 513 if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) { 514 /* msdn doc is incomplete here and wrong. 515 * The only formats that can be read directly here 516 * are DF16, DF24 and INTZ. 517 * Tested on win the swizzle is 518 * R = depth, G = B = 0, A = 1 for DF16 and DF24 519 * R = G = B = A = depth for INTZ 520 * For the other ZS formats that can't be read directly 521 * but can be used as shadow map, the result is duplicated on 522 * all channel */ 523 if (This->format == D3DFMT_DF16 || 524 This->format == D3DFMT_DF24) { 525 swizzle[1] = PIPE_SWIZZLE_0; 526 swizzle[2] = PIPE_SWIZZLE_0; 527 swizzle[3] = PIPE_SWIZZLE_1; 528 } else { 529 swizzle[1] = PIPE_SWIZZLE_X; 530 swizzle[2] = PIPE_SWIZZLE_X; 531 swizzle[3] = PIPE_SWIZZLE_X; 532 } 533 } else if (resource->format == PIPE_FORMAT_RGTC2_UNORM) { 534 swizzle[0] = PIPE_SWIZZLE_Y; 535 swizzle[1] = PIPE_SWIZZLE_X; 536 swizzle[2] = PIPE_SWIZZLE_1; 537 swizzle[3] = PIPE_SWIZZLE_1; 538 } else if (resource->format != PIPE_FORMAT_A8_UNORM && 539 resource->format != PIPE_FORMAT_RGTC1_UNORM) { 540 /* exceptions: 541 * A8 should have 0.0 as default values for RGB. 542 * ATI1/RGTC1 should be r 0 0 1 (tested on windows). 543 * It is already what gallium does. All the other ones 544 * should have 1.0 for non-defined values */ 545 for (i = 0; i < 4; i++) { 546 if (SWIZZLE_TO_REPLACE(desc->swizzle[i])) 547 swizzle[i] = PIPE_SWIZZLE_1; 548 } 549 } 550 551 /* if requested and supported, convert to the sRGB format */ 552 srgb_format = util_format_srgb(resource->format); 553 if (sRGB && srgb_format != PIPE_FORMAT_NONE && 554 screen->is_format_supported(screen, srgb_format, 555 resource->target, 0, 0, resource->bind)) 556 templ.format = srgb_format; 557 else 558 templ.format = resource->format; 559 templ.u.tex.first_layer = 0; 560 templ.u.tex.last_layer = resource->target == PIPE_TEXTURE_3D ? 561 0 : resource->array_size - 1; 562 templ.u.tex.first_level = 0; 563 templ.u.tex.last_level = resource->last_level; 564 templ.swizzle_r = swizzle[0]; 565 templ.swizzle_g = swizzle[1]; 566 templ.swizzle_b = swizzle[2]; 567 templ.swizzle_a = swizzle[3]; 568 templ.target = resource->target; 569 570 pipe = nine_context_get_pipe_acquire(This->base.base.device); 571 This->view[sRGB] = pipe->create_sampler_view(pipe, resource, &templ); 572 nine_context_get_pipe_release(This->base.base.device); 573 574 DBG("sampler view = %p(resource = %p)\n", This->view[sRGB], resource); 575 576 return This->view[sRGB] ? D3D_OK : D3DERR_DRIVERINTERNALERROR; 577} 578 579void NINE_WINAPI 580NineBaseTexture9_PreLoad( struct NineBaseTexture9 *This ) 581{ 582 DBG("This=%p\n", This); 583 584 if (This->base.pool == D3DPOOL_MANAGED) 585 NineBaseTexture9_UploadSelf(This); 586} 587 588void 589NineBaseTexture9_UnLoad( struct NineBaseTexture9 *This ) 590{ 591 DBG("This=%p\n", This); 592 593 if (This->base.pool != D3DPOOL_MANAGED || 594 This->managed.lod_resident == -1) 595 return; 596 597 DBG("This=%p, releasing resource\n", This); 598 pipe_resource_reference(&This->base.resource, NULL); 599 This->managed.lod_resident = -1; 600 This->managed.dirty = TRUE; 601 602 /* If the texture is bound, we have to re-upload it */ 603 BASETEX_REGISTER_UPDATE(This); 604} 605 606#if defined(DEBUG) || !defined(NDEBUG) 607void 608NineBaseTexture9_Dump( struct NineBaseTexture9 *This ) 609{ 610 DBG("\nNineBaseTexture9(%p->NULL/%p): Pool=%s Type=%s Usage=%s\n" 611 "Format=%s Dims=%ux%ux%u/%u LastLevel=%u Lod=%u(%u)\n", This, 612 This->base.resource, 613 nine_D3DPOOL_to_str(This->base.pool), 614 nine_D3DRTYPE_to_str(This->base.type), 615 nine_D3DUSAGE_to_str(This->base.usage), 616 d3dformat_to_string(This->format), 617 This->base.info.width0, This->base.info.height0, This->base.info.depth0, 618 This->base.info.array_size, This->base.info.last_level, 619 This->managed.lod, This->managed.lod_resident); 620} 621#endif /* DEBUG || !NDEBUG */ 622