fix texture reloads b/t opengl and directx

This commit is contained in:
David Rose 2008-12-20 02:23:06 +00:00
parent ec66c3cb10
commit 6c16f96c94
3 changed files with 103 additions and 74 deletions

View File

@ -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

View File

@ -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);

View File

@ -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.