mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
fix dx8 compressed textures; dx8 vs. dx9 cleanup
This commit is contained in:
parent
7db5f2c148
commit
cd69554707
@ -1867,6 +1867,24 @@ reset() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if compressed textures are supported
|
||||||
|
#define CHECK_FOR_DXTVERSION(num) \
|
||||||
|
if (_screen->_supported_tex_formats_mask & DXT##num##_FLAG) {\
|
||||||
|
if (dxgsg8_cat.is_debug()) {\
|
||||||
|
dxgsg8_cat.debug() << "Compressed texture format DXT" << #num << " supported \n";\
|
||||||
|
}\
|
||||||
|
_supports_compressed_texture = true;\
|
||||||
|
_compressed_texture_formats.set_bit(Texture::CM_dxt##num);\
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_FOR_DXTVERSION(1)
|
||||||
|
CHECK_FOR_DXTVERSION(2)
|
||||||
|
CHECK_FOR_DXTVERSION(3)
|
||||||
|
CHECK_FOR_DXTVERSION(4)
|
||||||
|
CHECK_FOR_DXTVERSION(5)
|
||||||
|
|
||||||
|
#undef CHECK_FOR_DXTVERSION
|
||||||
|
|
||||||
// s3 virge drivers sometimes give crap values for these
|
// s3 virge drivers sometimes give crap values for these
|
||||||
if (_screen->_d3dcaps.MaxTextureWidth == 0)
|
if (_screen->_d3dcaps.MaxTextureWidth == 0)
|
||||||
_screen->_d3dcaps.MaxTextureWidth = 256;
|
_screen->_d3dcaps.MaxTextureWidth = 256;
|
||||||
|
@ -74,34 +74,35 @@ create_texture(DXScreenData &scrn) {
|
|||||||
bool needs_luminance = false;
|
bool needs_luminance = false;
|
||||||
bool compress_texture = false;
|
bool compress_texture = false;
|
||||||
|
|
||||||
nassertr(IS_VALID_PTR(get_texture()), false);
|
Texture *tex = get_texture();
|
||||||
|
nassertr(IS_VALID_PTR(tex), false);
|
||||||
|
|
||||||
delete_texture();
|
delete_texture();
|
||||||
|
|
||||||
#ifdef DO_PSTATS
|
#ifdef DO_PSTATS
|
||||||
update_data_size_bytes(get_texture()->estimate_texture_memory());
|
update_data_size_bytes(tex->estimate_texture_memory());
|
||||||
#endif // DO_PSTATS
|
#endif // DO_PSTATS
|
||||||
|
|
||||||
// bpp indicates requested fmt, not texture fmt
|
// bpp indicates requested fmt, not texture fmt
|
||||||
DWORD target_bpp = get_bits_per_pixel(get_texture()->get_format(), &num_alpha_bits);
|
DWORD target_bpp = get_bits_per_pixel(tex->get_format(), &num_alpha_bits);
|
||||||
DWORD num_color_channels = get_texture()->get_num_components();
|
DWORD num_color_channels = tex->get_num_components();
|
||||||
|
|
||||||
//PRINT_REFCNT(dxgsg8, scrn._d3d8);
|
//PRINT_REFCNT(dxgsg8, scrn._d3d8);
|
||||||
|
|
||||||
DWORD orig_width = (DWORD)get_texture()->get_x_size();
|
DWORD orig_width = (DWORD)tex->get_x_size();
|
||||||
DWORD orig_height = (DWORD)get_texture()->get_y_size();
|
DWORD orig_height = (DWORD)tex->get_y_size();
|
||||||
DWORD orig_depth = (DWORD)get_texture()->get_z_size();
|
DWORD orig_depth = (DWORD)tex->get_z_size();
|
||||||
|
|
||||||
if ((get_texture()->get_format() == Texture::F_luminance_alpha)||
|
if ((tex->get_format() == Texture::F_luminance_alpha)||
|
||||||
(get_texture()->get_format() == Texture::F_luminance_alphamask) ||
|
(tex->get_format() == Texture::F_luminance_alphamask) ||
|
||||||
(get_texture()->get_format() == Texture::F_luminance)) {
|
(tex->get_format() == Texture::F_luminance)) {
|
||||||
needs_luminance = true;
|
needs_luminance = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num_alpha_bits > 0) {
|
if (num_alpha_bits > 0) {
|
||||||
if (num_color_channels == 3) {
|
if (num_color_channels == 3) {
|
||||||
dxgsg8_cat.error()
|
dxgsg8_cat.error()
|
||||||
<< "texture " << get_texture()->get_name()
|
<< "texture " << tex->get_name()
|
||||||
<< " has no inherent alpha channel, but alpha format is requested!\n";
|
<< " has no inherent alpha channel, but alpha format is requested!\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,16 +132,39 @@ create_texture(DXScreenData &scrn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check for texture compression
|
// check for texture compression
|
||||||
switch (get_texture()->get_texture_type()) {
|
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_1d_texture:
|
||||||
case Texture::TT_2d_texture:
|
case Texture::TT_2d_texture:
|
||||||
case Texture::TT_cube_map:
|
case Texture::TT_cube_map:
|
||||||
// check config setting
|
|
||||||
if (compressed_textures) {
|
|
||||||
// no compression for render target textures, or very small
|
// no compression for render target textures, or very small
|
||||||
// textures
|
// textures
|
||||||
if (get_texture()->get_render_to_texture() == false &&
|
if (tex->get_render_to_texture() == false &&
|
||||||
orig_width >= 4 && orig_height >= 4) {
|
orig_width >= 4 && orig_height >= 4) {
|
||||||
|
if (texture_wants_compressed){
|
||||||
compress_texture = true;
|
compress_texture = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,7 +183,7 @@ create_texture(DXScreenData &scrn) {
|
|||||||
|
|
||||||
DWORD filter_caps;
|
DWORD filter_caps;
|
||||||
|
|
||||||
switch (get_texture()->get_texture_type()) {
|
switch (tex->get_texture_type()) {
|
||||||
case Texture::TT_1d_texture:
|
case Texture::TT_1d_texture:
|
||||||
case Texture::TT_2d_texture:
|
case Texture::TT_2d_texture:
|
||||||
filter_caps = scrn._d3dcaps.TextureFilterCaps;
|
filter_caps = scrn._d3dcaps.TextureFilterCaps;
|
||||||
@ -253,15 +277,15 @@ create_texture(DXScreenData &scrn) {
|
|||||||
|
|
||||||
if (orig_width != target_width || orig_height != target_height ||
|
if (orig_width != target_width || orig_height != target_height ||
|
||||||
orig_depth != target_depth) {
|
orig_depth != target_depth) {
|
||||||
if (get_texture()->get_texture_type() == Texture::TT_3d_texture) {
|
if (tex->get_texture_type() == Texture::TT_3d_texture) {
|
||||||
dxgsg8_cat.info()
|
dxgsg8_cat.info()
|
||||||
<< "Reducing size of " << get_texture()->get_name()
|
<< "Reducing size of " << tex->get_name()
|
||||||
<< " from " << orig_width << "x" << orig_height << "x" << orig_depth
|
<< " from " << orig_width << "x" << orig_height << "x" << orig_depth
|
||||||
<< " to " << target_width << "x" << target_height
|
<< " to " << target_width << "x" << target_height
|
||||||
<< "x" << target_depth << "\n";
|
<< "x" << target_depth << "\n";
|
||||||
} else {
|
} else {
|
||||||
dxgsg8_cat.info()
|
dxgsg8_cat.info()
|
||||||
<< "Reducing size of " << get_texture()->get_name()
|
<< "Reducing size of " << tex->get_name()
|
||||||
<< " from " << orig_width << "x" << orig_height
|
<< " from " << orig_width << "x" << orig_height
|
||||||
<< " to " << target_width << "x" << target_height << "\n";
|
<< " to " << target_width << "x" << target_height << "\n";
|
||||||
}
|
}
|
||||||
@ -306,6 +330,26 @@ create_texture(DXScreenData &scrn) {
|
|||||||
|
|
||||||
if (!dx_force_16bpptextures) {
|
if (!dx_force_16bpptextures) {
|
||||||
if (compress_texture) {
|
if (compress_texture) {
|
||||||
|
if (texture_stored_compressed){
|
||||||
|
// if the texture is already compressed, we need to choose the corresponding format,
|
||||||
|
// otherwise we might end up cross-compressing from e.g. DXT5 to DXT3
|
||||||
|
switch (compression_mode){
|
||||||
|
case Texture::CM_dxt2:
|
||||||
|
CHECK_FOR_FMT(DXT2, Conv32toDXT2);
|
||||||
|
break;
|
||||||
|
case Texture::CM_dxt3:
|
||||||
|
CHECK_FOR_FMT(DXT3, Conv32toDXT3);
|
||||||
|
break;
|
||||||
|
case Texture::CM_dxt4:
|
||||||
|
CHECK_FOR_FMT(DXT4, Conv32toDXT4);
|
||||||
|
break;
|
||||||
|
case Texture::CM_dxt5:
|
||||||
|
CHECK_FOR_FMT(DXT5, Conv32toDXT5);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// if no compressed format matches, just fall trhough to pick a different format
|
||||||
|
}
|
||||||
|
else
|
||||||
CHECK_FOR_FMT(DXT3, Conv32toDXT3);
|
CHECK_FOR_FMT(DXT3, Conv32toDXT3);
|
||||||
}
|
}
|
||||||
if (num_color_channels == 4) {
|
if (num_color_channels == 4) {
|
||||||
@ -478,7 +522,7 @@ create_texture(DXScreenData &scrn) {
|
|||||||
|
|
||||||
// if we've gotten here, haven't found a match
|
// if we've gotten here, haven't found a match
|
||||||
dxgsg8_cat.error()
|
dxgsg8_cat.error()
|
||||||
<< error_message << ": " << get_texture()->get_name() << endl
|
<< error_message << ": " << tex->get_name() << endl
|
||||||
<< "NumColorChannels: " << num_color_channels << "; NumAlphaBits: "
|
<< "NumColorChannels: " << num_color_channels << "; NumAlphaBits: "
|
||||||
<< num_alpha_bits << "; targetbpp: " <<target_bpp
|
<< num_alpha_bits << "; targetbpp: " <<target_bpp
|
||||||
<< "; _supported_tex_formats_mask: 0x"
|
<< "; _supported_tex_formats_mask: 0x"
|
||||||
@ -491,7 +535,7 @@ create_texture(DXScreenData &scrn) {
|
|||||||
found_matching_format:
|
found_matching_format:
|
||||||
// We found a suitable format that matches the texture's format.
|
// We found a suitable format that matches the texture's format.
|
||||||
|
|
||||||
if (get_texture()->get_match_framebuffer_format()) {
|
if (tex->get_match_framebuffer_format()) {
|
||||||
// Instead of creating a texture with the found format, we will
|
// Instead of creating a texture with the found format, we will
|
||||||
// need to make one that exactly matches the framebuffer's
|
// need to make one that exactly matches the framebuffer's
|
||||||
// format. Look up what that format is.
|
// format. Look up what that format is.
|
||||||
@ -526,7 +570,7 @@ create_texture(DXScreenData &scrn) {
|
|||||||
|
|
||||||
Texture::FilterType ft;
|
Texture::FilterType ft;
|
||||||
|
|
||||||
ft = get_texture()->get_magfilter();
|
ft = tex->get_magfilter();
|
||||||
if ((ft != Texture::FT_linear) && ft != Texture::FT_nearest) {
|
if ((ft != Texture::FT_linear) && ft != Texture::FT_nearest) {
|
||||||
// mipmap settings make no sense for magfilter
|
// mipmap settings make no sense for magfilter
|
||||||
if (ft == Texture::FT_nearest_mipmap_nearest) {
|
if (ft == Texture::FT_nearest_mipmap_nearest) {
|
||||||
@ -540,10 +584,10 @@ create_texture(DXScreenData &scrn) {
|
|||||||
(filter_caps & D3DPTFILTERCAPS_MAGFLINEAR) == 0) {
|
(filter_caps & D3DPTFILTERCAPS_MAGFLINEAR) == 0) {
|
||||||
ft = Texture::FT_nearest;
|
ft = Texture::FT_nearest;
|
||||||
}
|
}
|
||||||
get_texture()->set_magfilter(ft);
|
tex->set_magfilter(ft);
|
||||||
|
|
||||||
// figure out if we are mipmapping this texture
|
// figure out if we are mipmapping this texture
|
||||||
ft = get_texture()->get_minfilter();
|
ft = tex->get_minfilter();
|
||||||
_has_mipmaps = false;
|
_has_mipmaps = false;
|
||||||
|
|
||||||
if (!dx_ignore_mipmaps) { // set if no HW mipmap capable
|
if (!dx_ignore_mipmaps) { // set if no HW mipmap capable
|
||||||
@ -561,11 +605,11 @@ create_texture(DXScreenData &scrn) {
|
|||||||
if (ft != Texture::FT_linear_mipmap_linear) {
|
if (ft != Texture::FT_linear_mipmap_linear) {
|
||||||
dxgsg8_cat.spam()
|
dxgsg8_cat.spam()
|
||||||
<< "Forcing trilinear mipmapping on DX texture ["
|
<< "Forcing trilinear mipmapping on DX texture ["
|
||||||
<< get_texture()->get_name() << "]\n";
|
<< tex->get_name() << "]\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ft = Texture::FT_linear_mipmap_linear;
|
ft = Texture::FT_linear_mipmap_linear;
|
||||||
get_texture()->set_minfilter(ft);
|
tex->set_minfilter(ft);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ((ft == Texture::FT_nearest_mipmap_nearest) || // cvt to no-mipmap filter types
|
} else if ((ft == Texture::FT_nearest_mipmap_nearest) || // cvt to no-mipmap filter types
|
||||||
@ -617,23 +661,23 @@ create_texture(DXScreenData &scrn) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
get_texture()->set_minfilter(ft);
|
tex->set_minfilter(ft);
|
||||||
|
|
||||||
uint aniso_degree;
|
uint aniso_degree;
|
||||||
|
|
||||||
aniso_degree = 1;
|
aniso_degree = 1;
|
||||||
if (scrn._d3dcaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) {
|
if (scrn._d3dcaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) {
|
||||||
aniso_degree = get_texture()->get_anisotropic_degree();
|
aniso_degree = tex->get_anisotropic_degree();
|
||||||
if ((aniso_degree>scrn._d3dcaps.MaxAnisotropy) ||
|
if ((aniso_degree>scrn._d3dcaps.MaxAnisotropy) ||
|
||||||
dx_force_anisotropic_filtering) {
|
dx_force_anisotropic_filtering) {
|
||||||
aniso_degree = scrn._d3dcaps.MaxAnisotropy;
|
aniso_degree = scrn._d3dcaps.MaxAnisotropy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
get_texture()->set_anisotropic_degree(aniso_degree);
|
tex->set_anisotropic_degree(aniso_degree);
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
dxgsg8_cat.spam()
|
dxgsg8_cat.spam()
|
||||||
<< "create_texture: setting aniso degree for " << get_texture()->get_name()
|
<< "create_texture: setting aniso degree for " << tex->get_name()
|
||||||
<< " to: " << aniso_degree << endl;
|
<< " to: " << aniso_degree << endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -645,7 +689,7 @@ create_texture(DXScreenData &scrn) {
|
|||||||
|
|
||||||
if (dxgsg8_cat.is_debug()) {
|
if (dxgsg8_cat.is_debug()) {
|
||||||
dxgsg8_cat.debug()
|
dxgsg8_cat.debug()
|
||||||
<< "create_texture: generating mipmaps for " << get_texture()->get_name()
|
<< "create_texture: generating mipmaps for " << tex->get_name()
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -656,7 +700,7 @@ create_texture(DXScreenData &scrn) {
|
|||||||
D3DPOOL pool;
|
D3DPOOL pool;
|
||||||
|
|
||||||
usage = 0;
|
usage = 0;
|
||||||
if (get_texture()->get_render_to_texture ()) {
|
if (tex->get_render_to_texture ()) {
|
||||||
// REQUIRED
|
// REQUIRED
|
||||||
pool = D3DPOOL_DEFAULT;
|
pool = D3DPOOL_DEFAULT;
|
||||||
if (support_render_texture && scrn._dxgsg8 -> get_supports_render_texture ( )) {
|
if (support_render_texture && scrn._dxgsg8 -> get_supports_render_texture ( )) {
|
||||||
@ -667,7 +711,7 @@ create_texture(DXScreenData &scrn) {
|
|||||||
pool = D3DPOOL_MANAGED;
|
pool = D3DPOOL_MANAGED;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (get_texture()->get_texture_type()) {
|
switch (tex->get_texture_type()) {
|
||||||
case Texture::TT_1d_texture:
|
case Texture::TT_1d_texture:
|
||||||
case Texture::TT_2d_texture:
|
case Texture::TT_2d_texture:
|
||||||
hr = scrn._d3d_device->CreateTexture
|
hr = scrn._d3d_device->CreateTexture
|
||||||
@ -699,7 +743,7 @@ create_texture(DXScreenData &scrn) {
|
|||||||
|
|
||||||
if (dxgsg8_cat.is_debug()) {
|
if (dxgsg8_cat.is_debug()) {
|
||||||
dxgsg8_cat.debug()
|
dxgsg8_cat.debug()
|
||||||
<< "create_texture: " << get_texture()->get_name()
|
<< "create_texture: " << tex->get_name()
|
||||||
<< " converting panda equivalent of " << D3DFormatStr(_d3d_format)
|
<< " converting panda equivalent of " << D3DFormatStr(_d3d_format)
|
||||||
<< " => " << D3DFormatStr(target_pixel_format) << endl;
|
<< " => " << D3DFormatStr(target_pixel_format) << endl;
|
||||||
}
|
}
|
||||||
@ -709,7 +753,7 @@ create_texture(DXScreenData &scrn) {
|
|||||||
goto error_exit;
|
goto error_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
get_texture()->texture_uploaded(scrn._dxgsg8);
|
tex->texture_uploaded(scrn._dxgsg8);
|
||||||
mark_loaded();
|
mark_loaded();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -1087,6 +1131,163 @@ d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface,
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: calculate_row_byte_length
|
||||||
|
// Access: Private, hidden
|
||||||
|
// Description: local helper function, which calculates the
|
||||||
|
// 'row_byte_length' or 'pitch' needed for calling
|
||||||
|
// D3DXLoadSurfaceFromMemory.
|
||||||
|
// Takes compressed formats (DXTn) into account.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
static UINT calculate_row_byte_length (int width, int num_color_channels, D3DFORMAT tex_format)
|
||||||
|
{
|
||||||
|
UINT source_row_byte_length = 0;
|
||||||
|
|
||||||
|
// check for compressed textures and adjust source_row_byte_length and source_format accordingly
|
||||||
|
switch (tex_format) {
|
||||||
|
case D3DFMT_DXT1:
|
||||||
|
// for dxt1 compressed textures, the row_byte_lenght is "the width of one row of cells, in bytes"
|
||||||
|
// cells are 4 pixels wide, take up 8 bytes, and at least 1 cell has to be there.
|
||||||
|
source_row_byte_length = max(1,width / 4)*8;
|
||||||
|
break;
|
||||||
|
case D3DFMT_DXT2:
|
||||||
|
case D3DFMT_DXT3:
|
||||||
|
case D3DFMT_DXT4:
|
||||||
|
case D3DFMT_DXT5:
|
||||||
|
// analogue as above, but cells take up 16 bytes
|
||||||
|
source_row_byte_length = max(1,width / 4)*16;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// no known compression format.. usual calculation
|
||||||
|
source_row_byte_length = width*num_color_channels;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return source_row_byte_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: DXTextureContext8::fill_d3d_texture_mipmap_pixels
|
||||||
|
// Access: Private
|
||||||
|
// Description: Called from fill_d3d_texture_pixels, this function
|
||||||
|
// fills a single mipmap with texture data.
|
||||||
|
// Takes care of all necessery conversions and error
|
||||||
|
// handling.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
HRESULT DXTextureContext8::fill_d3d_texture_mipmap_pixels(int mip_level, int depth_index, D3DFORMAT source_format)
|
||||||
|
{
|
||||||
|
// This whole function was refactored out of fill_d3d_texture_pixels to make the code
|
||||||
|
// more readable and to avoid code duplication.
|
||||||
|
IDirect3DSurface8 *mip_surface = NULL;
|
||||||
|
bool using_temp_buffer = false;
|
||||||
|
HRESULT hr = E_FAIL;
|
||||||
|
CPTA_uchar image = get_texture()->get_ram_mipmap_image(mip_level);
|
||||||
|
BYTE *pixels = (BYTE*) image.p();
|
||||||
|
DWORD width = (DWORD) get_texture()->get_expected_mipmap_x_size(mip_level);
|
||||||
|
DWORD height = (DWORD) get_texture()->get_expected_mipmap_y_size(mip_level);
|
||||||
|
int component_width = get_texture()->get_component_width();
|
||||||
|
|
||||||
|
pixels += depth_index * get_texture()->get_expected_ram_mipmap_page_size(mip_level);
|
||||||
|
|
||||||
|
if (get_texture()->get_texture_type() == Texture::TT_cube_map) {
|
||||||
|
nassertr(IS_VALID_PTR(_d3d_cube_texture), E_FAIL);
|
||||||
|
hr = _d3d_cube_texture->GetCubeMapSurface((D3DCUBEMAP_FACES)depth_index, mip_level, &mip_surface);
|
||||||
|
} else {
|
||||||
|
nassertr(IS_VALID_PTR(_d3d_2d_texture), E_FAIL);
|
||||||
|
hr = _d3d_2d_texture->GetSurfaceLevel(mip_level, &mip_surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
dxgsg8_cat.error()
|
||||||
|
<< "FillDDTextureMipmapPixels failed for " << get_texture()->get_name()
|
||||||
|
<< ", GetSurfaceLevel failed" << D3DERRORSTRING(hr);
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
RECT source_size;
|
||||||
|
source_size.left = source_size.top = 0;
|
||||||
|
source_size.right = width;
|
||||||
|
source_size.bottom = height;
|
||||||
|
|
||||||
|
UINT source_row_byte_length = calculate_row_byte_length(width, get_texture()->get_num_components(), source_format);
|
||||||
|
|
||||||
|
DWORD mip_filter;
|
||||||
|
// need filtering if size changes, (also if bitdepth reduced (need
|
||||||
|
// dithering)??)
|
||||||
|
mip_filter = D3DX_FILTER_LINEAR ; //| D3DX_FILTER_DITHER; //dithering looks ugly on i810 for 4444 textures
|
||||||
|
|
||||||
|
// D3DXLoadSurfaceFromMemory will load black luminance and we want
|
||||||
|
// full white, so convert to explicit luminance-alpha format
|
||||||
|
if (_d3d_format == D3DFMT_A8) {
|
||||||
|
// alloc buffer for explicit D3DFMT_A8L8
|
||||||
|
USHORT *temp_buffer = new USHORT[width * height];
|
||||||
|
if (!IS_VALID_PTR(temp_buffer)) {
|
||||||
|
dxgsg8_cat.error()
|
||||||
|
<< "FillDDTextureMipmapPixels couldnt alloc mem for temp pixbuf!\n";
|
||||||
|
goto exit_FillMipmapSurf;
|
||||||
|
}
|
||||||
|
using_temp_buffer = true;
|
||||||
|
|
||||||
|
USHORT *out_pixels = temp_buffer;
|
||||||
|
BYTE *source_pixels = pixels + component_width - 1;
|
||||||
|
for (UINT y = 0; y < height; y++) {
|
||||||
|
for (UINT x = 0; x < width; x++, source_pixels += component_width, out_pixels++) {
|
||||||
|
// add full white, which is our interpretation of alpha-only
|
||||||
|
// (similar to default adding full opaque alpha 0xFF to
|
||||||
|
// RGB-only textures)
|
||||||
|
*out_pixels = ((*source_pixels) << 8 ) | 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
source_format = D3DFMT_A8L8;
|
||||||
|
source_row_byte_length = width * sizeof(USHORT);
|
||||||
|
pixels = (BYTE*)temp_buffer;
|
||||||
|
}
|
||||||
|
else if (component_width != 1) {
|
||||||
|
// Convert from 16-bit per channel (or larger) format down to
|
||||||
|
// 8-bit per channel. This throws away precision in the
|
||||||
|
// original image, but dx8 doesn't support high-precision images
|
||||||
|
// anyway.
|
||||||
|
|
||||||
|
int num_components = get_texture()->get_num_components();
|
||||||
|
int num_pixels = width * height * num_components;
|
||||||
|
BYTE *temp_buffer = new BYTE[num_pixels];
|
||||||
|
if (!IS_VALID_PTR(temp_buffer)) {
|
||||||
|
dxgsg8_cat.error() << "FillDDTextureMipmapPixels couldnt alloc mem for temp pixbuf!\n";
|
||||||
|
goto exit_FillMipmapSurf;
|
||||||
|
}
|
||||||
|
using_temp_buffer = true;
|
||||||
|
|
||||||
|
BYTE *source_pixels = pixels + component_width - 1;
|
||||||
|
for (int i = 0; i < num_pixels; i++) {
|
||||||
|
temp_buffer[i] = *source_pixels;
|
||||||
|
source_pixels += component_width;
|
||||||
|
}
|
||||||
|
pixels = (BYTE*)temp_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// filtering may be done here if texture if targetsize != origsize
|
||||||
|
#ifdef DO_PSTATS
|
||||||
|
GraphicsStateGuardian::_data_transferred_pcollector.add_level(source_row_byte_length * height);
|
||||||
|
#endif
|
||||||
|
hr = D3DXLoadSurfaceFromMemory
|
||||||
|
(mip_surface, (PALETTEENTRY*)NULL, (RECT*)NULL, (LPCVOID)pixels,
|
||||||
|
source_format, source_row_byte_length, (PALETTEENTRY*)NULL,
|
||||||
|
&source_size, mip_filter, (D3DCOLOR)0x0);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
dxgsg8_cat.error()
|
||||||
|
<< "FillDDTextureMipmapPixels failed for " << get_texture()->get_name()
|
||||||
|
<< ", D3DXLoadSurfFromMem failed" << D3DERRORSTRING(hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit_FillMipmapSurf:
|
||||||
|
if (using_temp_buffer) {
|
||||||
|
SAFE_DELETE_ARRAY(pixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
RELEASE(mip_surface, dxgsg8, "FillDDTextureMipmapPixels MipSurface texture ptr", RELEASE_ONCE);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: DXTextureContext8::fill_d3d_texture_pixels
|
// Function: DXTextureContext8::fill_d3d_texture_pixels
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -1108,127 +1309,63 @@ fill_d3d_texture_pixels() {
|
|||||||
// operations or something.
|
// operations or something.
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
nassertr(IS_VALID_PTR((BYTE*)image.p()), E_FAIL);
|
||||||
|
nassertr(IS_VALID_PTR(_d3d_texture), E_FAIL);
|
||||||
|
|
||||||
PStatTimer timer(GraphicsStateGuardian::_load_texture_pcollector);
|
PStatTimer timer(GraphicsStateGuardian::_load_texture_pcollector);
|
||||||
|
|
||||||
nassertr(IS_VALID_PTR(_d3d_texture), E_FAIL);
|
|
||||||
|
|
||||||
DWORD orig_width = (DWORD) get_texture()->get_x_size();
|
|
||||||
DWORD orig_height = (DWORD) get_texture()->get_y_size();
|
|
||||||
DWORD orig_depth = (DWORD) get_texture()->get_z_size();
|
DWORD orig_depth = (DWORD) get_texture()->get_z_size();
|
||||||
DWORD num_color_channels = get_texture()->get_num_components();
|
|
||||||
D3DFORMAT source_format = _d3d_format;
|
D3DFORMAT source_format = _d3d_format;
|
||||||
BYTE *image_pixels = (BYTE*)image.p();
|
|
||||||
int component_width = get_texture()->get_component_width();
|
|
||||||
|
|
||||||
nassertr(IS_VALID_PTR(image_pixels), E_FAIL);
|
// check for compressed textures and adjust source_format accordingly
|
||||||
|
switch (get_texture()->get_ram_image_compression()) {
|
||||||
IDirect3DSurface8 *mip_level_0 = NULL;
|
case Texture::CM_dxt1:
|
||||||
bool using_temp_buffer = false;
|
source_format = D3DFMT_DXT1;
|
||||||
BYTE *pixels = NULL;
|
break;
|
||||||
|
case Texture::CM_dxt2:
|
||||||
|
source_format = D3DFMT_DXT2;
|
||||||
|
break;
|
||||||
|
case Texture::CM_dxt3:
|
||||||
|
source_format = D3DFMT_DXT3;
|
||||||
|
break;
|
||||||
|
case Texture::CM_dxt4:
|
||||||
|
source_format = D3DFMT_DXT4;
|
||||||
|
break;
|
||||||
|
case Texture::CM_dxt5:
|
||||||
|
source_format = D3DFMT_DXT5;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// no known compression format.. no adjustment
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned int di = 0; di < orig_depth; di++) {
|
for (unsigned int di = 0; di < orig_depth; di++) {
|
||||||
pixels = image_pixels + di * get_texture()->get_expected_ram_page_size();
|
|
||||||
mip_level_0 = NULL;
|
|
||||||
|
|
||||||
if (get_texture()->get_texture_type() == Texture::TT_cube_map) {
|
|
||||||
nassertr(IS_VALID_PTR(_d3d_cube_texture), E_FAIL);
|
|
||||||
hr = _d3d_cube_texture->GetCubeMapSurface((D3DCUBEMAP_FACES)di, 0, &mip_level_0);
|
|
||||||
} else {
|
|
||||||
nassertr(IS_VALID_PTR(_d3d_2d_texture), E_FAIL);
|
|
||||||
hr = _d3d_2d_texture->GetSurfaceLevel(0, &mip_level_0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// fill top level mipmap
|
||||||
|
hr = fill_d3d_texture_mipmap_pixels(0, di, source_format);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
dxgsg8_cat.error()
|
return hr; // error message was already output in fill_d3d_texture_mipmap_pixels
|
||||||
<< "FillDDSurfaceTexturePixels failed for " << get_texture()->get_name()
|
|
||||||
<< ", GetSurfaceLevel failed" << D3DERRORSTRING(hr);
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
RECT source_size;
|
|
||||||
source_size.left = source_size.top = 0;
|
|
||||||
source_size.right = orig_width;
|
|
||||||
source_size.bottom = orig_height;
|
|
||||||
|
|
||||||
UINT source_row_byte_length = orig_width * num_color_channels;
|
|
||||||
|
|
||||||
DWORD level_0_filter, mip_filter_flags;
|
|
||||||
using_temp_buffer = false;
|
|
||||||
|
|
||||||
// need filtering if size changes, (also if bitdepth reduced (need
|
|
||||||
// dithering)??)
|
|
||||||
level_0_filter = D3DX_FILTER_LINEAR ; //| D3DX_FILTER_DITHER; //dithering looks ugly on i810 for 4444 textures
|
|
||||||
|
|
||||||
// D3DXLoadSurfaceFromMemory will load black luminance and we want
|
|
||||||
// full white, so convert to explicit luminance-alpha format
|
|
||||||
if (_d3d_format == D3DFMT_A8) {
|
|
||||||
// alloc buffer for explicit D3DFMT_A8L8
|
|
||||||
USHORT *temp_buffer = new USHORT[orig_width * orig_height];
|
|
||||||
if (!IS_VALID_PTR(temp_buffer)) {
|
|
||||||
dxgsg8_cat.error()
|
|
||||||
<< "FillDDSurfaceTexturePixels couldnt alloc mem for temp pixbuf!\n";
|
|
||||||
goto exit_FillDDSurf;
|
|
||||||
}
|
|
||||||
using_temp_buffer = true;
|
|
||||||
|
|
||||||
USHORT *out_pixels = temp_buffer;
|
|
||||||
BYTE *source_pixels = pixels + component_width - 1;
|
|
||||||
for (UINT y = 0; y < orig_height; y++) {
|
|
||||||
for (UINT x = 0;
|
|
||||||
x < orig_width;
|
|
||||||
x++, source_pixels += component_width, out_pixels++) {
|
|
||||||
// add full white, which is our interpretation of alpha-only
|
|
||||||
// (similar to default adding full opaque alpha 0xFF to
|
|
||||||
// RGB-only textures)
|
|
||||||
*out_pixels = ((*source_pixels) << 8 ) | 0xFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
source_format = D3DFMT_A8L8;
|
|
||||||
source_row_byte_length = orig_width * sizeof(USHORT);
|
|
||||||
pixels = (BYTE*)temp_buffer;
|
|
||||||
|
|
||||||
} else if (component_width != 1) {
|
|
||||||
// Convert from 16-bit per channel (or larger) format down to
|
|
||||||
// 8-bit per channel. This throws away precision in the
|
|
||||||
// original image, but dx8 doesn't support high-precision images
|
|
||||||
// anyway.
|
|
||||||
|
|
||||||
int num_components = get_texture()->get_num_components();
|
|
||||||
int num_pixels = orig_width * orig_height * num_components;
|
|
||||||
BYTE *temp_buffer = new BYTE[num_pixels];
|
|
||||||
if (!IS_VALID_PTR(temp_buffer)) {
|
|
||||||
dxgsg8_cat.error() << "FillDDSurfaceTexturePixels couldnt alloc mem for temp pixbuf!\n";
|
|
||||||
goto exit_FillDDSurf;
|
|
||||||
}
|
|
||||||
using_temp_buffer = true;
|
|
||||||
|
|
||||||
BYTE *source_pixels = pixels + component_width - 1;
|
|
||||||
for (int i = 0; i < num_pixels; i++) {
|
|
||||||
temp_buffer[i] = *source_pixels;
|
|
||||||
source_pixels += component_width;
|
|
||||||
}
|
|
||||||
pixels = (BYTE*)temp_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// filtering may be done here if texture if targetsize != origsize
|
|
||||||
#ifdef DO_PSTATS
|
|
||||||
GraphicsStateGuardian::_data_transferred_pcollector.add_level(source_row_byte_length * orig_height);
|
|
||||||
#endif
|
|
||||||
hr = D3DXLoadSurfaceFromMemory
|
|
||||||
(mip_level_0, (PALETTEENTRY*)NULL, (RECT*)NULL, (LPCVOID)pixels,
|
|
||||||
source_format, source_row_byte_length, (PALETTEENTRY*)NULL,
|
|
||||||
&source_size, level_0_filter, (D3DCOLOR)0x0);
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
dxgsg8_cat.error()
|
|
||||||
<< "FillDDSurfaceTexturePixels failed for " << get_texture()->get_name()
|
|
||||||
<< ", D3DXLoadSurfFromMem failed" << D3DERRORSTRING(hr);
|
|
||||||
goto exit_FillDDSurf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_has_mipmaps) {
|
if (_has_mipmaps) {
|
||||||
|
// if we have pre-calculated mipmap levels, use them, otherwise generate on the fly
|
||||||
|
int miplevel_count = _d3d_2d_texture->GetLevelCount(); // what if it's not a 2d texture?
|
||||||
|
|
||||||
|
if (miplevel_count <= get_texture()->get_num_ram_mipmap_images()) {
|
||||||
|
dxgsg8_cat.debug()
|
||||||
|
<< "Using pre-calculated mipmap levels for texture " << get_texture()->get_name();
|
||||||
|
|
||||||
|
for (int mip_level = 1; mip_level < miplevel_count; ++mip_level) {
|
||||||
|
hr = fill_d3d_texture_mipmap_pixels(mip_level, di, source_format);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
return hr; // error message was already output in fill_d3d_texture_mipmap_pixels
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// mipmaps need to be generated.
|
||||||
|
|
||||||
|
DWORD mip_filter_flags;
|
||||||
if (!dx_use_triangle_mipgen_filter) {
|
if (!dx_use_triangle_mipgen_filter) {
|
||||||
mip_filter_flags = D3DX_FILTER_BOX;
|
mip_filter_flags = D3DX_FILTER_BOX;
|
||||||
} else {
|
} else {
|
||||||
@ -1236,28 +1373,18 @@ fill_d3d_texture_pixels() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// mip_filter_flags |= D3DX_FILTER_DITHER;
|
// mip_filter_flags |= D3DX_FILTER_DITHER;
|
||||||
|
|
||||||
hr = D3DXFilterTexture(_d3d_texture, (PALETTEENTRY*)NULL, 0,
|
hr = D3DXFilterTexture(_d3d_texture, (PALETTEENTRY*)NULL, 0,
|
||||||
mip_filter_flags);
|
mip_filter_flags);
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
dxgsg8_cat.error()
|
dxgsg8_cat.error()
|
||||||
<< "FillDDSurfaceTexturePixels failed for " << get_texture()->get_name()
|
<< "FillDDSurfaceTexturePixels failed for " << get_texture()->get_name()
|
||||||
<< ", D3DXFilterTex failed" << D3DERRORSTRING(hr);
|
<< ", D3DXFilterTex failed" << D3DERRORSTRING(hr);
|
||||||
goto exit_FillDDSurf;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (using_temp_buffer) {
|
|
||||||
SAFE_DELETE_ARRAY(pixels);
|
|
||||||
}
|
}
|
||||||
RELEASE(mip_level_0, dxgsg8, "FillDDSurf MipLev0 texture ptr", RELEASE_ONCE);
|
|
||||||
}
|
}
|
||||||
return hr;
|
|
||||||
|
|
||||||
exit_FillDDSurf:
|
|
||||||
if (using_temp_buffer) {
|
|
||||||
SAFE_DELETE_ARRAY(pixels);
|
|
||||||
}
|
|
||||||
RELEASE(mip_level_0, dxgsg8, "FillDDSurf MipLev0 texture ptr", RELEASE_ONCE);
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ public:
|
|||||||
int z);
|
int z);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
HRESULT fill_d3d_texture_mipmap_pixels(int mip_level, int depth_index, D3DFORMAT source_format);
|
||||||
HRESULT fill_d3d_texture_pixels();
|
HRESULT fill_d3d_texture_pixels();
|
||||||
HRESULT fill_d3d_volume_texture_pixels();
|
HRESULT fill_d3d_volume_texture_pixels();
|
||||||
static int down_to_power_2(int value);
|
static int down_to_power_2(int value);
|
||||||
|
@ -85,33 +85,34 @@ create_texture(DXScreenData &scrn) {
|
|||||||
bool needs_luminance = false;
|
bool needs_luminance = false;
|
||||||
bool compress_texture = false;
|
bool compress_texture = false;
|
||||||
|
|
||||||
nassertr(IS_VALID_PTR(get_texture()), false);
|
Texture *tex = get_texture();
|
||||||
|
nassertr(IS_VALID_PTR(tex), false);
|
||||||
|
|
||||||
delete_texture();
|
delete_texture();
|
||||||
|
|
||||||
// bpp indicates requested fmt, not texture fmt
|
// bpp indicates requested fmt, not texture fmt
|
||||||
DWORD target_bpp = get_bits_per_pixel(get_texture()->get_format(), &num_alpha_bits);
|
DWORD target_bpp = get_bits_per_pixel(tex->get_format(), &num_alpha_bits);
|
||||||
DWORD num_color_channels = get_texture()->get_num_components();
|
DWORD num_color_channels = tex->get_num_components();
|
||||||
|
|
||||||
// printf ("format = %d \n", get_texture()->get_format());
|
// printf ("format = %d \n", tex->get_format());
|
||||||
// printf ("target_bpp %d, num_color_channels %d num_alpha_bits %d \n", target_bpp, num_color_channels, num_alpha_bits);
|
// printf ("target_bpp %d, num_color_channels %d num_alpha_bits %d \n", target_bpp, num_color_channels, num_alpha_bits);
|
||||||
|
|
||||||
//PRINT_REFCNT(dxgsg9, scrn._d3d9);
|
//PRINT_REFCNT(dxgsg9, scrn._d3d9);
|
||||||
|
|
||||||
DWORD orig_width = (DWORD)get_texture()->get_x_size();
|
DWORD orig_width = (DWORD)tex->get_x_size();
|
||||||
DWORD orig_height = (DWORD)get_texture()->get_y_size();
|
DWORD orig_height = (DWORD)tex->get_y_size();
|
||||||
DWORD orig_depth = (DWORD)get_texture()->get_z_size();
|
DWORD orig_depth = (DWORD)tex->get_z_size();
|
||||||
|
|
||||||
if ((get_texture()->get_format() == Texture::F_luminance_alpha)||
|
if ((tex->get_format() == Texture::F_luminance_alpha)||
|
||||||
(get_texture()->get_format() == Texture::F_luminance_alphamask) ||
|
(tex->get_format() == Texture::F_luminance_alphamask) ||
|
||||||
(get_texture()->get_format() == Texture::F_luminance)) {
|
(tex->get_format() == Texture::F_luminance)) {
|
||||||
needs_luminance = true;
|
needs_luminance = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num_alpha_bits > 0) {
|
if (num_alpha_bits > 0) {
|
||||||
if (num_color_channels == 3) {
|
if (num_color_channels == 3) {
|
||||||
dxgsg9_cat.error()
|
dxgsg9_cat.error()
|
||||||
<< "texture " << get_texture()->get_name()
|
<< "texture " << tex->get_name()
|
||||||
<< " has no inherent alpha channel, but alpha format is requested!\n";
|
<< " has no inherent alpha channel, but alpha format is requested!\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,26 +142,19 @@ create_texture(DXScreenData &scrn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check for texture compression
|
// check for texture compression
|
||||||
Texture::CompressionMode compression_mode = Texture::CM_off;
|
|
||||||
bool texture_stored_compressed = false;
|
|
||||||
bool texture_wants_compressed = false;
|
bool texture_wants_compressed = false;
|
||||||
|
Texture::CompressionMode compression_mode = tex->get_ram_image_compression();
|
||||||
compression_mode = get_texture()->get_ram_image_compression();
|
bool texture_stored_compressed = compression_mode != Texture::CM_off;
|
||||||
// assert my assumption that CM_dxt1..CM_dxt5 enum values are ascending without gaps
|
|
||||||
nassertr(((Texture::CM_dxt1+1)==Texture::CM_dxt2)&&((Texture::CM_dxt2+1)==Texture::CM_dxt3)&&((Texture::CM_dxt3+1)==Texture::CM_dxt4)&&((Texture::CM_dxt4+1)==Texture::CM_dxt5),false);
|
|
||||||
if ((compression_mode >= Texture::CM_dxt1) && (compression_mode <= Texture::CM_dxt5)) {
|
|
||||||
texture_stored_compressed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (texture_stored_compressed) {
|
if (texture_stored_compressed) {
|
||||||
texture_wants_compressed = true;
|
texture_wants_compressed = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (get_texture()->get_compression() == Texture::CM_off) {
|
if (tex->get_compression() == Texture::CM_off) {
|
||||||
// no compression
|
// no compression
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (get_texture()->get_compression() == Texture::CM_default) {
|
if (tex->get_compression() == Texture::CM_default) {
|
||||||
// default = use "compressed-textures" config setting
|
// default = use "compressed-textures" config setting
|
||||||
if (compressed_textures) {
|
if (compressed_textures) {
|
||||||
texture_wants_compressed = true;
|
texture_wants_compressed = true;
|
||||||
@ -172,13 +166,13 @@ create_texture(DXScreenData &scrn) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (get_texture()->get_texture_type()) {
|
switch (tex->get_texture_type()) {
|
||||||
case Texture::TT_1d_texture:
|
case Texture::TT_1d_texture:
|
||||||
case Texture::TT_2d_texture:
|
case Texture::TT_2d_texture:
|
||||||
case Texture::TT_cube_map:
|
case Texture::TT_cube_map:
|
||||||
// no compression for render target textures, or very small
|
// no compression for render target textures, or very small
|
||||||
// textures
|
// textures
|
||||||
if (!get_texture()->get_render_to_texture() &&
|
if (!tex->get_render_to_texture() &&
|
||||||
orig_width >= 4 && orig_height >= 4) {
|
orig_width >= 4 && orig_height >= 4) {
|
||||||
if (texture_wants_compressed){
|
if (texture_wants_compressed){
|
||||||
compress_texture = true;
|
compress_texture = true;
|
||||||
@ -199,7 +193,7 @@ create_texture(DXScreenData &scrn) {
|
|||||||
|
|
||||||
DWORD filter_caps;
|
DWORD filter_caps;
|
||||||
|
|
||||||
switch (get_texture()->get_texture_type()) {
|
switch (tex->get_texture_type()) {
|
||||||
case Texture::TT_1d_texture:
|
case Texture::TT_1d_texture:
|
||||||
case Texture::TT_2d_texture:
|
case Texture::TT_2d_texture:
|
||||||
filter_caps = scrn._d3dcaps.TextureFilterCaps;
|
filter_caps = scrn._d3dcaps.TextureFilterCaps;
|
||||||
@ -293,15 +287,15 @@ create_texture(DXScreenData &scrn) {
|
|||||||
|
|
||||||
if (orig_width != target_width || orig_height != target_height ||
|
if (orig_width != target_width || orig_height != target_height ||
|
||||||
orig_depth != target_depth) {
|
orig_depth != target_depth) {
|
||||||
if (get_texture()->get_texture_type() == Texture::TT_3d_texture) {
|
if (tex->get_texture_type() == Texture::TT_3d_texture) {
|
||||||
dxgsg9_cat.info()
|
dxgsg9_cat.info()
|
||||||
<< "Reducing size of " << get_texture()->get_name()
|
<< "Reducing size of " << tex->get_name()
|
||||||
<< " from " << orig_width << "x" << orig_height << "x" << orig_depth
|
<< " from " << orig_width << "x" << orig_height << "x" << orig_depth
|
||||||
<< " to " << target_width << "x" << target_height
|
<< " to " << target_width << "x" << target_height
|
||||||
<< "x" << target_depth << "\n";
|
<< "x" << target_depth << "\n";
|
||||||
} else {
|
} else {
|
||||||
dxgsg9_cat.info()
|
dxgsg9_cat.info()
|
||||||
<< "Reducing size of " << get_texture()->get_name()
|
<< "Reducing size of " << tex->get_name()
|
||||||
<< " from " << orig_width << "x" << orig_height
|
<< " from " << orig_width << "x" << orig_height
|
||||||
<< " to " << target_width << "x" << target_height << "\n";
|
<< " to " << target_width << "x" << target_height << "\n";
|
||||||
}
|
}
|
||||||
@ -559,7 +553,7 @@ create_texture(DXScreenData &scrn) {
|
|||||||
|
|
||||||
// if we've gotten here, haven't found a match
|
// if we've gotten here, haven't found a match
|
||||||
dxgsg9_cat.error()
|
dxgsg9_cat.error()
|
||||||
<< error_message << ": " << get_texture()->get_name() << endl
|
<< error_message << ": " << tex->get_name() << endl
|
||||||
<< "NumColorChannels: " << num_color_channels << "; NumAlphaBits: "
|
<< "NumColorChannels: " << num_color_channels << "; NumAlphaBits: "
|
||||||
<< num_alpha_bits << "; targetbpp: " <<target_bpp
|
<< num_alpha_bits << "; targetbpp: " <<target_bpp
|
||||||
<< "; _supported_tex_formats_mask: 0x"
|
<< "; _supported_tex_formats_mask: 0x"
|
||||||
@ -572,7 +566,7 @@ create_texture(DXScreenData &scrn) {
|
|||||||
found_matching_format:
|
found_matching_format:
|
||||||
// We found a suitable format that matches the texture's format.
|
// We found a suitable format that matches the texture's format.
|
||||||
|
|
||||||
if (get_texture()->get_match_framebuffer_format()) {
|
if (tex->get_match_framebuffer_format()) {
|
||||||
// Instead of creating a texture with the found format, we will
|
// Instead of creating a texture with the found format, we will
|
||||||
// need to make one that exactly matches the framebuffer's
|
// need to make one that exactly matches the framebuffer's
|
||||||
// format. Look up what that format is.
|
// format. Look up what that format is.
|
||||||
@ -610,7 +604,7 @@ create_texture(DXScreenData &scrn) {
|
|||||||
|
|
||||||
Texture::FilterType ft;
|
Texture::FilterType ft;
|
||||||
|
|
||||||
ft = get_texture()->get_magfilter();
|
ft = tex->get_magfilter();
|
||||||
if ((ft != Texture::FT_linear) && ft != Texture::FT_nearest) {
|
if ((ft != Texture::FT_linear) && ft != Texture::FT_nearest) {
|
||||||
// mipmap settings make no sense for magfilter
|
// mipmap settings make no sense for magfilter
|
||||||
if (ft == Texture::FT_nearest_mipmap_nearest) {
|
if (ft == Texture::FT_nearest_mipmap_nearest) {
|
||||||
@ -624,10 +618,10 @@ create_texture(DXScreenData &scrn) {
|
|||||||
(filter_caps & D3DPTFILTERCAPS_MAGFLINEAR) == 0) {
|
(filter_caps & D3DPTFILTERCAPS_MAGFLINEAR) == 0) {
|
||||||
ft = Texture::FT_nearest;
|
ft = Texture::FT_nearest;
|
||||||
}
|
}
|
||||||
get_texture()->set_magfilter(ft);
|
tex->set_magfilter(ft);
|
||||||
|
|
||||||
// figure out if we are mipmapping this texture
|
// figure out if we are mipmapping this texture
|
||||||
ft = get_texture()->get_minfilter();
|
ft = tex->get_minfilter();
|
||||||
_has_mipmaps = false;
|
_has_mipmaps = false;
|
||||||
|
|
||||||
if (!dx_ignore_mipmaps) { // set if no HW mipmap capable
|
if (!dx_ignore_mipmaps) { // set if no HW mipmap capable
|
||||||
@ -645,11 +639,11 @@ create_texture(DXScreenData &scrn) {
|
|||||||
if (ft != Texture::FT_linear_mipmap_linear) {
|
if (ft != Texture::FT_linear_mipmap_linear) {
|
||||||
dxgsg9_cat.spam()
|
dxgsg9_cat.spam()
|
||||||
<< "Forcing trilinear mipmapping on DX texture ["
|
<< "Forcing trilinear mipmapping on DX texture ["
|
||||||
<< get_texture()->get_name() << "]\n";
|
<< tex->get_name() << "]\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ft = Texture::FT_linear_mipmap_linear;
|
ft = Texture::FT_linear_mipmap_linear;
|
||||||
get_texture()->set_minfilter(ft);
|
tex->set_minfilter(ft);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ((ft == Texture::FT_nearest_mipmap_nearest) || // cvt to no-mipmap filter types
|
} else if ((ft == Texture::FT_nearest_mipmap_nearest) || // cvt to no-mipmap filter types
|
||||||
@ -701,23 +695,23 @@ create_texture(DXScreenData &scrn) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
get_texture()->set_minfilter(ft);
|
tex->set_minfilter(ft);
|
||||||
|
|
||||||
uint aniso_degree;
|
uint aniso_degree;
|
||||||
|
|
||||||
aniso_degree = 1;
|
aniso_degree = 1;
|
||||||
if (scrn._d3dcaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) {
|
if (scrn._d3dcaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) {
|
||||||
aniso_degree = get_texture()->get_anisotropic_degree();
|
aniso_degree = tex->get_anisotropic_degree();
|
||||||
if ((aniso_degree>scrn._d3dcaps.MaxAnisotropy) ||
|
if ((aniso_degree>scrn._d3dcaps.MaxAnisotropy) ||
|
||||||
dx_force_anisotropic_filtering) {
|
dx_force_anisotropic_filtering) {
|
||||||
aniso_degree = scrn._d3dcaps.MaxAnisotropy;
|
aniso_degree = scrn._d3dcaps.MaxAnisotropy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
get_texture()->set_anisotropic_degree(aniso_degree);
|
tex->set_anisotropic_degree(aniso_degree);
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
dxgsg9_cat.spam()
|
dxgsg9_cat.spam()
|
||||||
<< "create_texture: setting aniso degree for " << get_texture()->get_name()
|
<< "create_texture: setting aniso degree for " << tex->get_name()
|
||||||
<< " to: " << aniso_degree << endl;
|
<< " to: " << aniso_degree << endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -729,7 +723,7 @@ create_texture(DXScreenData &scrn) {
|
|||||||
|
|
||||||
if (dxgsg9_cat.is_debug()) {
|
if (dxgsg9_cat.is_debug()) {
|
||||||
dxgsg9_cat.debug()
|
dxgsg9_cat.debug()
|
||||||
<< "create_texture: generating mipmaps for " << get_texture()->get_name()
|
<< "create_texture: generating mipmaps for " << tex->get_name()
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -740,7 +734,7 @@ create_texture(DXScreenData &scrn) {
|
|||||||
D3DPOOL pool;
|
D3DPOOL pool;
|
||||||
|
|
||||||
usage = 0;
|
usage = 0;
|
||||||
if (get_texture()->get_render_to_texture ( )) {
|
if (tex->get_render_to_texture ( )) {
|
||||||
// REQUIRED PARAMETERS
|
// REQUIRED PARAMETERS
|
||||||
_managed = false;
|
_managed = false;
|
||||||
pool = D3DPOOL_DEFAULT;
|
pool = D3DPOOL_DEFAULT;
|
||||||
@ -866,7 +860,7 @@ create_texture(DXScreenData &scrn) {
|
|||||||
if (_has_mipmaps) {
|
if (_has_mipmaps) {
|
||||||
data_size = (int) ((float) data_size * 1.3f);
|
data_size = (int) ((float) data_size * 1.3f);
|
||||||
}
|
}
|
||||||
if (get_texture()->get_texture_type() == Texture::TT_cube_map) {
|
if (tex->get_texture_type() == Texture::TT_cube_map) {
|
||||||
data_size *= 6;
|
data_size *= 6;
|
||||||
}
|
}
|
||||||
update_data_size_bytes(data_size);
|
update_data_size_bytes(data_size);
|
||||||
@ -876,7 +870,7 @@ create_texture(DXScreenData &scrn) {
|
|||||||
attempts = 0;
|
attempts = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
switch (get_texture()->get_texture_type()) {
|
switch (tex->get_texture_type()) {
|
||||||
case Texture::TT_1d_texture:
|
case Texture::TT_1d_texture:
|
||||||
case Texture::TT_2d_texture:
|
case Texture::TT_2d_texture:
|
||||||
hr = scrn._d3d_device->CreateTexture
|
hr = scrn._d3d_device->CreateTexture
|
||||||
@ -916,7 +910,7 @@ create_texture(DXScreenData &scrn) {
|
|||||||
|
|
||||||
if (DEBUG_TEXTURES && dxgsg9_cat.is_debug()) {
|
if (DEBUG_TEXTURES && dxgsg9_cat.is_debug()) {
|
||||||
dxgsg9_cat.debug()
|
dxgsg9_cat.debug()
|
||||||
<< "create_texture: " << get_texture()->get_name()
|
<< "create_texture: " << tex->get_name()
|
||||||
<< " converting panda equivalent of " << D3DFormatStr(_d3d_format)
|
<< " converting panda equivalent of " << D3DFormatStr(_d3d_format)
|
||||||
<< " => " << D3DFormatStr(target_pixel_format) << endl;
|
<< " => " << D3DFormatStr(target_pixel_format) << endl;
|
||||||
}
|
}
|
||||||
@ -933,7 +927,7 @@ create_texture(DXScreenData &scrn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// must not put render to texture into LRU
|
// must not put render to texture into LRU
|
||||||
if (!_managed && !get_texture()->get_render_to_texture()) {
|
if (!_managed && !tex->get_render_to_texture()) {
|
||||||
if (_lru_page == 0) {
|
if (_lru_page == 0) {
|
||||||
Lru *lru;
|
Lru *lru;
|
||||||
|
|
||||||
@ -945,14 +939,14 @@ create_texture(DXScreenData &scrn) {
|
|||||||
if (lru_page) {
|
if (lru_page) {
|
||||||
lru_page -> _m.v.type = GPT_Texture;
|
lru_page -> _m.v.type = GPT_Texture;
|
||||||
lru_page -> _m.lru_page_type.pointer = this;
|
lru_page -> _m.lru_page_type.pointer = this;
|
||||||
lru_page -> _m.name = get_texture()->get_filename();
|
lru_page -> _m.name = tex->get_filename();
|
||||||
|
|
||||||
lru -> add_cached_page (LPP_New, lru_page);
|
lru -> add_cached_page (LPP_New, lru_page);
|
||||||
_lru_page = lru_page;
|
_lru_page = lru_page;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
get_texture()->texture_uploaded(scrn._dxgsg9);
|
tex->texture_uploaded(scrn._dxgsg9);
|
||||||
}
|
}
|
||||||
mark_loaded();
|
mark_loaded();
|
||||||
|
|
||||||
@ -1505,7 +1499,6 @@ fill_d3d_texture_pixels(bool supports_automatic_mipmap_generation, IDirect3DDev
|
|||||||
nassertr(IS_VALID_PTR(get_texture()), E_FAIL);
|
nassertr(IS_VALID_PTR(get_texture()), E_FAIL);
|
||||||
|
|
||||||
CPTA_uchar image = get_texture()->get_ram_image();
|
CPTA_uchar image = get_texture()->get_ram_image();
|
||||||
|
|
||||||
if (image.is_null()) {
|
if (image.is_null()) {
|
||||||
// The texture doesn't have an image to load. That's ok; it
|
// The texture doesn't have an image to load. That's ok; it
|
||||||
// might be a texture we've rendered to by frame buffer
|
// might be a texture we've rendered to by frame buffer
|
||||||
@ -1556,10 +1549,7 @@ fill_d3d_texture_pixels(bool supports_automatic_mipmap_generation, IDirect3DDev
|
|||||||
DWORD orig_depth = (DWORD) get_texture()->get_z_size();
|
DWORD orig_depth = (DWORD) get_texture()->get_z_size();
|
||||||
D3DFORMAT source_format = _d3d_format;
|
D3DFORMAT source_format = _d3d_format;
|
||||||
|
|
||||||
nassertr(IS_VALID_PTR((BYTE*)image.p()), E_FAIL);
|
|
||||||
|
|
||||||
// check for compressed textures and adjust source_format accordingly
|
// check for compressed textures and adjust source_format accordingly
|
||||||
if (get_texture()->get_compression() != Texture::CM_off) {
|
|
||||||
switch (get_texture()->get_ram_image_compression()) {
|
switch (get_texture()->get_ram_image_compression()) {
|
||||||
case Texture::CM_dxt1:
|
case Texture::CM_dxt1:
|
||||||
source_format = D3DFMT_DXT1;
|
source_format = D3DFMT_DXT1;
|
||||||
@ -1580,7 +1570,6 @@ fill_d3d_texture_pixels(bool supports_automatic_mipmap_generation, IDirect3DDev
|
|||||||
// no known compression format.. no adjustment
|
// no known compression format.. no adjustment
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned int di = 0; di < orig_depth; di++) {
|
for (unsigned int di = 0; di < orig_depth; di++) {
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user