diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index 7ce6bac61f..2c22033c3a 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -160,13 +160,6 @@ prepare_texture(Texture *tex) { return NULL; } - if (!upload_texture(dtc)) { - dxgsg8_cat.error() - << "Unable to create texture " << *tex << endl; - delete dtc; - return NULL; - } - return dtc; } @@ -184,25 +177,17 @@ apply_texture(int i, TextureContext *tc) { _d3d_device->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_DISABLE); return; } + if (!update_texture(tc, false)) { + // Couldn't get the texture image or something. + _d3d_device->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_DISABLE); + return; + } tc->set_active(true); DXTextureContext8 *dtc = DCAST(DXTextureContext8, tc); Texture *tex = tc->get_texture(); - // If the texture image has changed, or if its use of mipmaps has - // changed, we need to re-create the image. - - if (dtc->was_modified()) { - if (!upload_texture(dtc)) { - // Oops, we can't re-create the texture for some reason. - dxgsg8_cat.error() - << "Unable to re-create texture " << *tex << endl; - _d3d_device->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_DISABLE); - return; - } - } - Texture::WrapMode wrap_u, wrap_v, wrap_w; wrap_u = tex->get_wrap_u(); wrap_v = tex->get_wrap_v(); @@ -259,6 +244,43 @@ apply_texture(int i, TextureContext *tc) { _d3d_device->SetTexture(i, dtc->get_d3d_texture()); } +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian8::update_texture +// Access: Public, Virtual +// Description: Ensures that the current Texture data is refreshed +// onto the GSG. This means updating the texture +// properties and/or re-uploading the texture image, if +// necessary. This should only be called within the +// draw thread. +// +// If force is true, this function will not return until +// the texture has been fully uploaded. If force is +// false, the function may choose to upload a simple +// version of the texture instead, if the texture is not +// fully resident (and if get_incomplete_render() is +// true). +//////////////////////////////////////////////////////////////////// +bool DXGraphicsStateGuardian8:: +update_texture(TextureContext *tc, bool force) { + DXTextureContext8 *dtc = DCAST(DXTextureContext8, tc); + + // If the texture image has changed, or if its use of mipmaps has + // changed, we need to re-create the image. + + if (dtc->was_modified()) { + if (!upload_texture(dtc, force)) { + // Oops, we can't re-create the texture for some reason. + Texture *tex = tc->get_texture(); + dxgsg8_cat.error() + << "Unable to re-create texture " << *tex << endl; + cerr << "b\n"; + return false; + } + } + + return true; +} + //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian8::upload_texture // Access: Public @@ -266,7 +288,7 @@ apply_texture(int i, TextureContext *tc) { // fills it with its pixel data. //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian8:: -upload_texture(DXTextureContext8 *dtc) { +upload_texture(DXTextureContext8 *dtc, bool force) { Texture *tex = dtc->get_texture(); if (!get_supports_compressed_texture_format(tex->get_ram_image_compression())) { dxgsg8_cat.error() @@ -274,7 +296,7 @@ upload_texture(DXTextureContext8 *dtc) { return false; } - if (_incomplete_render) { + if (_incomplete_render && !force) { bool has_image = _supports_compressed_texture ? tex->has_ram_image() : tex->has_uncompressed_ram_image(); if (!has_image && tex->might_have_ram_image() && tex->has_simple_ram_image() && diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h index fc5c810f09..c491049430 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h @@ -50,7 +50,8 @@ public: virtual TextureContext *prepare_texture(Texture *tex); void apply_texture(int i, TextureContext *tc); - bool upload_texture(DXTextureContext8 *dtc); + virtual bool update_texture(TextureContext *tc, bool force); + bool upload_texture(DXTextureContext8 *dtc, bool force); virtual void release_texture(TextureContext *tc); virtual bool extract_texture_data(Texture *tex); diff --git a/panda/src/dxgsg8/wdxGraphicsBuffer8.cxx b/panda/src/dxgsg8/wdxGraphicsBuffer8.cxx index a4929b540b..09a24bbb6a 100644 --- a/panda/src/dxgsg8/wdxGraphicsBuffer8.cxx +++ b/panda/src/dxgsg8/wdxGraphicsBuffer8.cxx @@ -284,20 +284,27 @@ rebuild_bitplanes() { color_ctx = DCAST(DXTextureContext8, color_tex->prepare_now(_gsg->get_prepared_objects(), _gsg)); - if (color_tex->get_texture_type() == Texture::TT_2d_texture) { - color_d3d_tex = color_ctx->_d3d_2d_texture; - nassertr(color_d3d_tex != 0, false); - hr = color_d3d_tex -> GetSurfaceLevel(0, &color_surf); - if (!SUCCEEDED(hr)) { - dxgsg8_cat.error ( ) << "GetSurfaceLevel " << D3DERRORSTRING(hr) FL; + if (color_ctx) { + if (!color_ctx->create_texture(*_dxgsg->_screen)) { + dxgsg8_cat.error() + << "Unable to re-create texture " << *color_ctx->get_texture() << endl; + return false; } - } else { - color_cube = color_ctx->_d3d_cube_texture; - nassertr(color_cube != 0, false); - if (_cube_map_index >= 0 && _cube_map_index < 6) { - hr = color_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &color_surf); + if (color_tex->get_texture_type() == Texture::TT_2d_texture) { + color_d3d_tex = color_ctx->_d3d_2d_texture; + nassertr(color_d3d_tex != 0, false); + hr = color_d3d_tex -> GetSurfaceLevel(0, &color_surf); if (!SUCCEEDED(hr)) { - dxgsg8_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL; + dxgsg8_cat.error ( ) << "GetSurfaceLevel " << D3DERRORSTRING(hr) FL; + } + } else { + color_cube = color_ctx->_d3d_cube_texture; + nassertr(color_cube != 0, false); + if (_cube_map_index >= 0 && _cube_map_index < 6) { + hr = color_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &color_surf); + if (!SUCCEEDED(hr)) { + dxgsg8_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL; + } } } } @@ -332,19 +339,27 @@ rebuild_bitplanes() { depth_ctx = DCAST(DXTextureContext8, depth_tex->prepare_now(_gsg->get_prepared_objects(), _gsg)); - if (depth_tex->get_texture_type() == Texture::TT_2d_texture) { - depth_d3d_tex = depth_ctx->_d3d_2d_texture; - nassertr(depth_d3d_tex != 0, false); - hr = color_d3d_tex -> GetSurfaceLevel(0, &depth_surf); - if (!SUCCEEDED(hr)) { - dxgsg8_cat.error ( ) << "GetSurfaceLevel " << D3DERRORSTRING(hr) FL; + if (depth_ctx) { + if (!depth_ctx->create_texture(*_dxgsg->_screen)) { + dxgsg8_cat.error() + << "Unable to re-create texture " << *color_ctx->get_texture() << endl; + return false; } - } else { - depth_cube = depth_ctx->_d3d_cube_texture; - nassertr(depth_cube != 0, false); - hr = depth_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &depth_surf); - if (!SUCCEEDED(hr)) { - dxgsg8_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL; + + if (depth_tex->get_texture_type() == Texture::TT_2d_texture) { + depth_d3d_tex = depth_ctx->_d3d_2d_texture; + nassertr(depth_d3d_tex != 0, false); + hr = color_d3d_tex -> GetSurfaceLevel(0, &depth_surf); + if (!SUCCEEDED(hr)) { + dxgsg8_cat.error ( ) << "GetSurfaceLevel " << D3DERRORSTRING(hr) FL; + } + } else { + depth_cube = depth_ctx->_d3d_cube_texture; + nassertr(depth_cube != 0, false); + hr = depth_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &depth_surf); + if (!SUCCEEDED(hr)) { + dxgsg8_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL; + } } } } @@ -409,6 +424,11 @@ select_cube_map(int cube_map_index) { color_ctx = DCAST(DXTextureContext8, color_tex->prepare_now(_gsg->get_prepared_objects(), _gsg)); + if (!color_ctx->create_texture(*_dxgsg->_screen)) { + dxgsg8_cat.error() + << "Unable to re-create texture " << *color_ctx->get_texture() << endl; + return; + } color_cube = color_ctx->_d3d_cube_texture; diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index 493a3b5913..b2354f3d2f 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -207,13 +207,6 @@ prepare_texture(Texture *tex) { return NULL; } - if (!upload_texture(dtc)) { - dxgsg9_cat.error() - << "Unable to create texture " << *tex << endl; - delete dtc; - return NULL; - } - return dtc; } @@ -231,28 +224,20 @@ apply_texture(int i, TextureContext *tc) { set_texture_stage_state(i, D3DTSS_COLOROP, D3DTOP_DISABLE); return; } + if (!update_texture(tc, false)) { + // Couldn't get the texture image or something. + set_texture_stage_state(i, D3DTSS_COLOROP, D3DTOP_DISABLE); + return; + } tc->set_active(true); DXTextureContext9 *dtc = DCAST(DXTextureContext9, tc); + Texture *tex = tc->get_texture(); if (_lru) { _lru -> access_page (dtc -> _lru_page); } - Texture *tex = tc->get_texture(); - - // If the texture image has changed, or if its use of mipmaps has - // changed, we need to re-create the image. - - if (dtc->was_modified()) { - if (!upload_texture(dtc)) { - // Oops, we can't re-create the texture for some reason. - dxgsg9_cat.error() - << "Unable to re-create texture " << *tex << endl; - set_texture_stage_state(i, D3DTSS_COLOROP, D3DTOP_DISABLE); - return; - } - } Texture::WrapMode wrap_u, wrap_v, wrap_w; @@ -321,6 +306,43 @@ apply_texture(int i, TextureContext *tc) { _d3d_device->SetTexture(i, dtc->get_d3d_texture()); } +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian9::update_texture +// Access: Public, Virtual +// Description: Ensures that the current Texture data is refreshed +// onto the GSG. This means updating the texture +// properties and/or re-uploading the texture image, if +// necessary. This should only be called within the +// draw thread. +// +// If force is true, this function will not return until +// the texture has been fully uploaded. If force is +// false, the function may choose to upload a simple +// version of the texture instead, if the texture is not +// fully resident (and if get_incomplete_render() is +// true). +//////////////////////////////////////////////////////////////////// +bool DXGraphicsStateGuardian9:: +update_texture(TextureContext *tc, bool force) { + DXTextureContext9 *dtc = DCAST(DXTextureContext9, tc); + + // If the texture image has changed, or if its use of mipmaps has + // changed, we need to re-create the image. + + if (dtc->was_modified()) { + if (!upload_texture(dtc, force)) { + // Oops, we can't re-create the texture for some reason. + Texture *tex = tc->get_texture(); + dxgsg9_cat.error() + << "Unable to re-create texture " << *tex << endl; + cerr << "b\n"; + return false; + } + } + + return true; +} + //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian9::upload_texture // Access: Public @@ -328,7 +350,7 @@ apply_texture(int i, TextureContext *tc) { // fills it with its pixel data. //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian9:: -upload_texture(DXTextureContext9 *dtc) { +upload_texture(DXTextureContext9 *dtc, bool force) { Texture *tex = dtc->get_texture(); if (!get_supports_compressed_texture_format(tex->get_ram_image_compression())) { dxgsg9_cat.error() @@ -336,7 +358,7 @@ upload_texture(DXTextureContext9 *dtc) { return false; } - if (_incomplete_render) { + if (_incomplete_render && !force) { bool has_image = _supports_compressed_texture ? tex->has_ram_image() : tex->has_uncompressed_ram_image(); if (!has_image && tex->might_have_ram_image() && tex->has_simple_ram_image() && diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h index 260c4cc423..e8f5b0590b 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h @@ -84,7 +84,8 @@ public: virtual TextureContext *prepare_texture(Texture *tex); void apply_texture(int i, TextureContext *tc); - bool upload_texture(DXTextureContext9 *dtc); + virtual bool update_texture(TextureContext *tc, bool force); + bool upload_texture(DXTextureContext9 *dtc, bool force); virtual void release_texture(TextureContext *tc); virtual bool extract_texture_data(Texture *tex); diff --git a/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx b/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx index 93fee962d4..6f3494fef3 100644 --- a/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx @@ -314,7 +314,13 @@ rebuild_bitplanes() { color_ctx = DCAST(DXTextureContext9, color_tex->prepare_now(_gsg->get_prepared_objects(), _gsg)); + if (color_ctx) { + if (!color_ctx->create_texture(*_dxgsg->_screen)) { + dxgsg9_cat.error() + << "Unable to re-create texture " << *color_ctx->get_texture() << endl; + return false; + } if (color_tex->get_texture_type() == Texture::TT_2d_texture) { color_d3d_tex = color_ctx->_d3d_2d_texture; nassertr(color_d3d_tex != 0, false); @@ -387,6 +393,11 @@ rebuild_bitplanes() { DCAST(DXTextureContext9, depth_tex->prepare_now(_gsg->get_prepared_objects(), _gsg)); if (depth_ctx) { + if (!depth_ctx->create_texture(*_dxgsg->_screen)) { + dxgsg9_cat.error() + << "Unable to re-create texture " << *color_ctx->get_texture() << endl; + return false; + } if (depth_tex->get_texture_type() == Texture::TT_2d_texture) { depth_d3d_tex = depth_ctx->_d3d_2d_texture; nassertr(depth_d3d_tex != 0, false); @@ -476,6 +487,11 @@ select_cube_map(int cube_map_index) { color_ctx = DCAST(DXTextureContext9, color_tex->prepare_now(_gsg->get_prepared_objects(), _gsg)); + if (!color_ctx->create_texture(*_dxgsg->_screen)) { + dxgsg9_cat.error() + << "Unable to re-create texture " << *color_ctx->get_texture() << endl; + return; + } color_cube = color_ctx->_d3d_cube_texture;