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