diff --git a/panda/src/dxgsg9/dxTextureContext9.cxx b/panda/src/dxgsg9/dxTextureContext9.cxx index 49a65fedc8..cb18813e20 100755 --- a/panda/src/dxgsg9/dxTextureContext9.cxx +++ b/panda/src/dxgsg9/dxTextureContext9.cxx @@ -123,6 +123,68 @@ create_texture(DXScreenData &scrn) { Texture *tex = get_texture(); nassertr(IS_VALID_PTR(tex), false); + // Ensure the ram image is loaded, if available. + tex->get_ram_image(); + + DWORD orig_width = (DWORD)tex->get_x_size(); + DWORD orig_height = (DWORD)tex->get_y_size(); + DWORD orig_depth = (DWORD)tex->get_z_size(); + + // check for texture compression + bool texture_wants_compressed = false; + Texture::CompressionMode compression_mode = tex->get_ram_image_compression(); + bool texture_stored_compressed = compression_mode != Texture::CM_off; + + if (texture_stored_compressed) { + texture_wants_compressed = true; + } else { + if (tex->get_compression() == Texture::CM_off) { + // no compression + } else { + if (tex->get_compression() == Texture::CM_default) { + // default = use "compressed-textures" config setting + if (compressed_textures) { + texture_wants_compressed = true; + } + } else { + texture_wants_compressed = true; + } + } + } + + switch (tex->get_texture_type()) { + case Texture::TT_1d_texture: + case Texture::TT_2d_texture: + case Texture::TT_cube_map: + // no compression for render target textures, or very small + // textures + if (!tex->get_render_to_texture() && + orig_width >= 4 && orig_height >= 4) { + if (texture_wants_compressed){ + compress_texture = true; + } + } + break; + case Texture::TT_3d_texture: + // compression of 3d textures not supported by all video chips + break; + } + + if (texture_stored_compressed && !compress_texture) { + // If we're going to need to reload the texture to get its + // uncompressed image, we'd better do so now, *before* we figure + // out the source format. We have to do this early, even though + // we're going to do it again in fill_d3d_texture_pixels(), + // because sometimes reloading the original ram image will change + // the texture's apparent pixel format (the compressed form may + // have a different format than the uncompressed form). + tex->get_uncompressed_ram_image(); + + orig_width = (DWORD)tex->get_x_size(); + orig_height = (DWORD)tex->get_y_size(); + orig_depth = (DWORD)tex->get_z_size(); + } + // bpp indicates requested fmt, not texture fmt DWORD target_bpp = get_bits_per_pixel(tex->get_format(), &num_alpha_bits); DWORD num_color_channels = tex->get_num_components(); @@ -132,10 +194,6 @@ create_texture(DXScreenData &scrn) { //PRINT_REFCNT(dxgsg9, scrn._d3d9); - DWORD orig_width = (DWORD)tex->get_x_size(); - DWORD orig_height = (DWORD)tex->get_y_size(); - DWORD orig_depth = (DWORD)tex->get_z_size(); - if ((tex->get_format() == Texture::F_luminance_alpha)|| (tex->get_format() == Texture::F_luminance_alphamask) || (tex->get_format() == Texture::F_luminance)) { @@ -173,49 +231,6 @@ create_texture(DXScreenData &scrn) { _d3d_format = D3DFMT_A8R8G8B8; break; } - - // check for texture compression - bool texture_wants_compressed = false; - Texture::CompressionMode compression_mode = tex->get_ram_image_compression(); - bool texture_stored_compressed = compression_mode != Texture::CM_off; - - if (texture_stored_compressed) { - texture_wants_compressed = true; - } - else { - if (tex->get_compression() == Texture::CM_off) { - // no compression - } - else { - if (tex->get_compression() == Texture::CM_default) { - // default = use "compressed-textures" config setting - if (compressed_textures) { - texture_wants_compressed = true; - } - } - else { - texture_wants_compressed = true; - } - } - } - - switch (tex->get_texture_type()) { - case Texture::TT_1d_texture: - case Texture::TT_2d_texture: - case Texture::TT_cube_map: - // no compression for render target textures, or very small - // textures - if (!tex->get_render_to_texture() && - orig_width >= 4 && orig_height >= 4) { - if (texture_wants_compressed){ - compress_texture = true; - } - } - break; - case Texture::TT_3d_texture: - // compression of 3d textures not supported by all video chips - break; - } // make sure we handled all the possible cases nassertr(_d3d_format != D3DFMT_UNKNOWN, false); @@ -813,10 +828,10 @@ create_texture(DXScreenData &scrn) { int data_size; data_size = target_width * target_height * target_depth; - data_size = (int) ((float) data_size * bytes_per_texel); if (_has_mipmaps) { - data_size = (int) ((float) data_size * 1.3f); + data_size = (int) ((float) data_size * 1.3333333f); } + data_size = (int) ((float) data_size * bytes_per_texel); if (tex->get_texture_type() == Texture::TT_cube_map) { data_size *= 6; } @@ -829,6 +844,21 @@ create_texture(DXScreenData &scrn) { << "Creating " << *tex << ", " << data_size << " bytes, " << scrn._d3d_device->GetAvailableTextureMem() << " reported available.\n"; + dxgsg9_cat.debug() + << " size is " << target_width << " w * " << target_height << " h * " + << target_depth << " d"; + if (_has_mipmaps) { + dxgsg9_cat.debug(false) + << " * 1.3333333 mipmaps"; + } + dxgsg9_cat.debug(false) + << " * " << bytes_per_texel << " bpt"; + if (tex->get_texture_type() == Texture::TT_cube_map) { + dxgsg9_cat.debug(false) + << " * 6 faces"; + } + dxgsg9_cat.debug(false) + << "\n"; } attempts = 0; @@ -879,7 +909,7 @@ create_texture(DXScreenData &scrn) { << " => " << D3DFormatStr(target_pixel_format) << endl; } - hr = fill_d3d_texture_pixels(scrn); + hr = fill_d3d_texture_pixels(scrn, compress_texture); if (FAILED(hr)) { dxgsg9_cat.debug () @@ -1650,7 +1680,7 @@ exit_FillMipmapSurf: // Description: //////////////////////////////////////////////////////////////////// HRESULT DXTextureContext9:: -fill_d3d_texture_pixels(DXScreenData &scrn) { +fill_d3d_texture_pixels(DXScreenData &scrn, bool compress_texture) { IDirect3DDevice9 *device = scrn._d3d_device; Texture *tex = get_texture(); nassertr(IS_VALID_PTR(tex), E_FAIL); @@ -1661,29 +1691,22 @@ fill_d3d_texture_pixels(DXScreenData &scrn) { HRESULT hr = E_FAIL; CPTA_uchar image; - if (scrn._dxgsg9->get_supports_compressed_texture()) { + Texture::CompressionMode image_compression = Texture::CM_off; + if (compress_texture) { + // If we are to be compressing this texture, accept a + // pre-compressed ram image if it is already so. image = tex->get_ram_image(); + if (!image.is_null()) { + image_compression = tex->get_ram_image_compression(); + } } else { + // If we are not to be compressing this texture, we can only + // accept an uncompressed ram image. Ask the texture to give us + // one, so that there's no danger of accidentally getting a + // pre-compressed image. image = tex->get_uncompressed_ram_image(); } - Texture::CompressionMode image_compression; - if (image.is_null()) { - image_compression = Texture::CM_off; - } else { - image_compression = tex->get_ram_image_compression(); - } - - if (!scrn._dxgsg9->get_supports_compressed_texture_format(image_compression) || - tex->get_x_size() < 4 || tex->get_y_size() < 4) { - // If we don't support this particular compression method, or in - // any case if the texture is too small (DirectX won't accept a - // small compressed texture), then fetch and load the uncompressed - // version instead. - image = tex->get_uncompressed_ram_image(); - image_compression = Texture::CM_off; - } - if (image.is_null()) { // The texture doesn't have an image to load. That's ok; it // might be a texture we've rendered to by frame buffer @@ -1750,7 +1773,7 @@ fill_d3d_texture_pixels(DXScreenData &scrn) { DWORD orig_depth = (DWORD) tex->get_z_size(); D3DFORMAT source_format = _d3d_format; - + // check for compressed textures and adjust source_format accordingly switch (image_compression) { case Texture::CM_dxt1: @@ -1772,7 +1795,7 @@ fill_d3d_texture_pixels(DXScreenData &scrn) { // no known compression format.. no adjustment break; } - + for (unsigned int di = 0; di < orig_depth; di++) { // fill top level mipmap diff --git a/panda/src/dxgsg9/dxTextureContext9.h b/panda/src/dxgsg9/dxTextureContext9.h index af7cde8814..128546d235 100755 --- a/panda/src/dxgsg9/dxTextureContext9.h +++ b/panda/src/dxgsg9/dxTextureContext9.h @@ -50,7 +50,7 @@ public: private: HRESULT fill_d3d_texture_mipmap_pixels(int mip_level, int depth_index, D3DFORMAT source_format); - HRESULT fill_d3d_texture_pixels(DXScreenData &scrn); + HRESULT fill_d3d_texture_pixels(DXScreenData &scrn, bool compress_texture); HRESULT fill_d3d_volume_texture_pixels(DXScreenData &scrn); static int down_to_power_2(int value); unsigned int get_bits_per_pixel(Texture::Format format, int *alphbits); diff --git a/panda/src/gobj/texture.cxx b/panda/src/gobj/texture.cxx index 50495903f5..ee07266187 100644 --- a/panda/src/gobj/texture.cxx +++ b/panda/src/gobj/texture.cxx @@ -2907,7 +2907,13 @@ do_unlock_and_reload_ram_image(bool allow_compression) { } // Then make sure we still need to reload before continuing. - if (_loaded_from_image && !do_has_ram_image() && !_fullpath.empty()) { + bool has_ram_image = do_has_ram_image(); + if (has_ram_image && !allow_compression && get_ram_image_compression() != Texture::CM_off) { + // If we don't want compression, but the ram image we have is + // pre-compressed, we don't consider it. + has_ram_image = false; + } + if (_loaded_from_image && !has_ram_image && !_fullpath.empty()) { nassertv(!_reloading); _reloading = true; @@ -2955,7 +2961,7 @@ do_reload_ram_image(bool allow_compression) { allow_compression = false; } - if ((cache->get_cache_textures() || (do_has_compression() && cache->get_cache_compressed_textures())) && !textures_header_only) { + if ((cache->get_cache_textures() || (allow_compression && cache->get_cache_compressed_textures())) && !textures_header_only) { // See if the texture can be found in the on-disk cache, if it is // active.