From 1b28d90ea90a12e5a9a4fa39cafb5b9b8edd42f5 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sat, 13 Jun 2026 12:35:55 +0200 Subject: [PATCH 1/3] refactor(textureloader): Simplify code in Texture Loader (#2789) --- .../Source/WWVegas/WW3D2/textureloader.cpp | 420 ++++++------------ 1 file changed, 129 insertions(+), 291 deletions(-) diff --git a/Core/Libraries/Source/WWVegas/WW3D2/textureloader.cpp b/Core/Libraries/Source/WWVegas/WW3D2/textureloader.cpp index f46cffff6ee..d3c56f57370 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/textureloader.cpp +++ b/Core/Libraries/Source/WWVegas/WW3D2/textureloader.cpp @@ -1296,6 +1296,33 @@ void TextureLoadTaskClass::Apply(bool initialize) D3DTexture = nullptr; } + +static unsigned Get_Requested_Reduction(unsigned width, unsigned height, unsigned mip_count) +{ + // Figure out correct reduction + unsigned reqReduction = WW3D::Get_Texture_Reduction(); + + // Leave only the lowest level + if (reqReduction >= max(mip_count, 1u)) + reqReduction = mip_count-1; + + // Clamp reduction + unsigned curReduction = 0; + unsigned curWidth = width; + unsigned curHeight = height; + unsigned minDim = WW3D::Get_Texture_Min_Dimension(); + + while (curReduction < reqReduction && curWidth > minDim && curHeight > minDim) + { + curWidth >>= 1; + curHeight >>= 1; + curReduction++; + } + + return curReduction; +} + + static bool Get_Texture_Information ( const char* filename, @@ -1315,7 +1342,8 @@ static bool Get_Texture_Information if (compressed) { DDSFileClass dds_file(filename, 0); - if (!dds_file.Is_Available()) return false; + if (!dds_file.Is_Available()) + return false; // Destination size will be the next power of two square from the larger width and height... w = dds_file.Get_Width(0); @@ -1323,24 +1351,8 @@ static bool Get_Texture_Information d = dds_file.Get_Depth(0); format = dds_file.Get_Format(); mip_count = dds_file.Get_Mip_Level_Count(); - //Figure out correct reduction - int reqReduction=WW3D::Get_Texture_Reduction(); //requested reduction - - if (reqReduction >= mip_count) - reqReduction=mip_count-1; //leave only the lowest level - - //Clamp reduction - int curReduction=0; - int curWidth=w; - int curHeight=h; - int minDim=WW3D::Get_Texture_Min_Dimension(); - - while (curReduction < reqReduction && curWidth > minDim && curHeight > minDim) - { curWidth >>=1; //keep dividing - curHeight >>=1; - curReduction++; - } - reduction=curReduction; + reduction = Get_Requested_Reduction(w, h, mip_count); + return true; } @@ -1354,35 +1366,17 @@ static bool Get_Texture_Information WW3DFormat dest_format; Get_WW3D_Format(dest_format,format,bpp,targa); + // Figure out how many mip levels this texture will occupy mip_count = 0; - - //Figure out how many mip levels this texture will occupy for (int i=targa.Header.Width, j=targa.Header.Height; i > 0 && j > 0; i>>=1, j>>=1) mip_count++; - //Figure out correct reduction - int reqReduction=WW3D::Get_Texture_Reduction(); //requested reduction - - if (reqReduction >= mip_count) - reqReduction=mip_count-1; //leave only the lowest level - - //Clamp reduction - int curReduction=0; - int curWidth=targa.Header.Width; - int curHeight=targa.Header.Height; - int minDim=WW3D::Get_Texture_Min_Dimension(); - - while (curReduction < reqReduction && curWidth > minDim && curHeight > minDim) - { curWidth >>=1; //keep dividing - curHeight >>=1; - curReduction++; - } - reduction=curReduction; - // Destination size will be the next power of two square from the larger width and height... w = targa.Header.Width; h = targa.Header.Height; d = 1; + reduction = Get_Requested_Reduction(w, h, mip_count); + return true; } @@ -1406,15 +1400,15 @@ static bool Get_Texture_Information bool TextureLoadTaskClass::Begin_Compressed_Load() { - unsigned orig_w,orig_h,orig_d,orig_mip_count,reduction; + unsigned orig_width,orig_height,orig_depth,orig_mip_count,orig_reduction; WW3DFormat orig_format; if (!Get_Texture_Information ( Texture->Get_Full_Path(), - reduction, - orig_w, - orig_h, - orig_d, + orig_reduction, + orig_width, + orig_height, + orig_depth, orig_format, orig_mip_count, true @@ -1425,24 +1419,24 @@ bool TextureLoadTaskClass::Begin_Compressed_Load() } // Destination size will be the next power of two square from the larger width and height... - unsigned int width = orig_w; - unsigned int height = orig_h; - TextureLoader::Validate_Texture_Size(width, height,orig_d); + unsigned int width = orig_width; + unsigned int height = orig_height; + TextureLoader::Validate_Texture_Size(width, height,orig_depth); // If the size doesn't match, try and see if texture reduction would help... (mainly for // cases where loaded texture is larger than hardware limit) - if (width != orig_w || height != orig_h) + if (width != orig_width || height != orig_height) { for (unsigned int i = 1; i < orig_mip_count; ++i) { - unsigned w=orig_w>>i; + unsigned w=orig_width>>i; if (w<4) w=4; - unsigned h=orig_h>>i; + unsigned h=orig_height>>i; if (h<4) h=4; unsigned tmp_w=w; unsigned tmp_h=h; - TextureLoader::Validate_Texture_Size(w,h,orig_d); + TextureLoader::Validate_Texture_Size(w,h,orig_depth); if (w == tmp_w && h == tmp_h) { @@ -1457,7 +1451,7 @@ bool TextureLoadTaskClass::Begin_Compressed_Load() Width = width; Height = height; Format = Get_Valid_Texture_Format(orig_format, Texture->Is_Compression_Allowed()); - Reduction = reduction; + Reduction = orig_reduction; if (!Texture->Is_Reducible() || Texture->MipLevelCount == MIP_LEVELS_1) @@ -1472,31 +1466,24 @@ bool TextureLoadTaskClass::Begin_Compressed_Load() Reduction = 0; //should not be possible to get here, but check just in case. unsigned int mip_level_count = Get_Mip_Level_Count(); - int reducedWidth=Width; - int reducedHeight=Height; + int reduced_width = Width >> Reduction; + int reduced_height = Height >> Reduction; // If texture wants all mip levels, take as many as the file contains (not necessarily all) // Otherwise take as many mip levels as the texture wants, not to exceed the count in file... - if (!mip_level_count) + if (mip_level_count == 0) { - reducedWidth >>= Reduction; - reducedHeight >>= Reduction; - mip_level_count = orig_mip_count-Reduction;//dds_file.Get_Mip_Level_Count(); + mip_level_count = orig_mip_count-Reduction; if (mip_level_count < 1) mip_level_count = 1; //sanity check to make sure something gets loaded. } else { if (mip_level_count > orig_mip_count) - { //dds_file.Get_Mip_Level_Count()) { - mip_level_count = orig_mip_count;//dds_file.Get_Mip_Level_Count(); - } - - if (Reduction) - { reducedWidth >>= Reduction; - reducedHeight >>= Reduction; - mip_level_count -= Reduction; //reduced requested number by those removed. + { + mip_level_count = orig_mip_count; } + mip_level_count -= Reduction; //reduced requested number by those removed. } // Once more, verify that the mip level count is correct (in case it was changed here it might not @@ -1519,8 +1506,8 @@ bool TextureLoadTaskClass::Begin_Compressed_Load() D3DTexture = DX8Wrapper::_Create_DX8_Texture ( - reducedWidth, - reducedHeight, + reduced_width, + reduced_height, Format, (MipCountType)mip_level_count, #ifdef USE_MANAGED_TEXTURES @@ -1537,15 +1524,15 @@ bool TextureLoadTaskClass::Begin_Compressed_Load() bool TextureLoadTaskClass::Begin_Uncompressed_Load() { - unsigned width,height,depth,orig_mip_count,reduction; + unsigned orig_width,orig_height,orig_depth,orig_mip_count,orig_reduction; WW3DFormat orig_format; if (!Get_Texture_Information ( Texture->Get_Full_Path(), - reduction, - width, - height, - depth, + orig_reduction, + orig_width, + orig_height, + orig_depth, orig_format, orig_mip_count, false @@ -1567,17 +1554,17 @@ bool TextureLoadTaskClass::Begin_Uncompressed_Load() } // Destination size will be the next power of two square from the larger width and height... - unsigned ow = width; - unsigned oh = height; - TextureLoader::Validate_Texture_Size(width, height,depth); - if (width != ow || height != oh) + unsigned ow = orig_width; + unsigned oh = orig_height; + TextureLoader::Validate_Texture_Size(orig_width, orig_height,orig_depth); + if (orig_width != ow || orig_height != oh) { - WWDEBUG_SAY(("Invalid texture size, scaling required. Texture: %s, size: %d x %d -> %d x %d", Texture->Get_Full_Path().str(), ow, oh, width, height)); + WWDEBUG_SAY(("Invalid texture size, scaling required. Texture: %s, size: %d x %d -> %d x %d", Texture->Get_Full_Path().str(), ow, oh, orig_width, orig_height)); } - Width = width; - Height = height; - Reduction = reduction; + Width = orig_width; + Height = orig_height; + Reduction = orig_reduction; if (!Texture->Is_Reducible() || Texture->MipLevelCount == MIP_LEVELS_1) Reduction = 0; //app doesn't want this texture to ever be reduced. @@ -1593,7 +1580,6 @@ bool TextureLoadTaskClass::Begin_Uncompressed_Load() if (Format == WW3D_FORMAT_UNKNOWN) { Format=dest_format; - // Format = Get_Valid_Texture_Format(dest_format, false); validated above } else { @@ -1628,150 +1614,6 @@ bool TextureLoadTaskClass::Begin_Uncompressed_Load() return true; } -/* -bool TextureLoadTaskClass::Begin_Compressed_Load() -{ - DDSFileClass dds_file(Texture->Get_Full_Path(), Get_Reduction()); - if (!dds_file.Is_Available()) { - return false; - } - - // Destination size will be the next power of two square from the larger width and height... - unsigned int width = dds_file.Get_Width(0); - unsigned int height = dds_file.Get_Height(0); - TextureLoader::Validate_Texture_Size(width, height); - - // If the size doesn't match, try and see if texture reduction would help... (mainly for - // cases where loaded texture is larger than hardware limit) - if (width != dds_file.Get_Width(0) || height != dds_file.Get_Height(0)) { - for (unsigned int i = 1; i < dds_file.Get_Mip_Level_Count(); ++i) { - unsigned int w = dds_file.Get_Width(i); - unsigned int h = dds_file.Get_Height(i); - TextureLoader::Validate_Texture_Size(w,h); - - if (w == dds_file.Get_Width(i) && h == dds_file.Get_Height(i)) { - Reduction += i; - width = w; - height = h; - break; - } - } - } - - Width = width; - Height = height; - Format = Get_Valid_Texture_Format(dds_file.Get_Format(), Texture->Is_Compression_Allowed()); - - unsigned int mip_level_count = Get_Mip_Level_Count(); - - // If texture wants all mip levels, take as many as the file contains (not necessarily all) - // Otherwise take as many mip levels as the texture wants, not to exceed the count in file... - if (!mip_level_count) { - mip_level_count = dds_file.Get_Mip_Level_Count(); - } else if (mip_level_count > dds_file.Get_Mip_Level_Count()) { - mip_level_count = dds_file.Get_Mip_Level_Count(); - } - - // Once more, verify that the mip level count is correct (in case it was changed here it might not - // match the size...well actually it doesn't have to match but it can't be bigger than the size) - unsigned int max_mip_level_count = 1; - unsigned int w = 4; - unsigned int h = 4; - - while (w < Width && h < Height) { - w += w; - h += h; - max_mip_level_count++; - } - - if (mip_level_count > max_mip_level_count) { - mip_level_count = max_mip_level_count; - } - - D3DTexture = DX8Wrapper::_Create_DX8_Texture( - Width, - Height, - Format, - (TextureBaseClass::MipCountType)mip_level_count, -#ifdef USE_MANAGED_TEXTURES - D3DPOOL_MANAGED); -#else - D3DPOOL_SYSTEMMEM); -#endif - MipLevelCount = mip_level_count; - return true; -} - - -bool TextureLoadTaskClass::Begin_Uncompressed_Load() -{ - Targa targa; - if (TARGA_ERROR_HANDLER(targa.Open(Texture->Get_Full_Path(), TGA_READMODE), Texture->Get_Full_Path())) { - return false; - } - - unsigned int bpp; - WW3DFormat src_format, dest_format; - Get_WW3D_Format(dest_format,src_format,bpp,targa); - - if ( src_format != WW3D_FORMAT_A8R8G8B8 - && src_format != WW3D_FORMAT_R8G8B8 - && src_format != WW3D_FORMAT_X8R8G8B8) { - WWDEBUG_SAY(("Invalid TGA format used in %s - only 24 and 32 bit formats should be used!", Texture->Get_Full_Path())); - } - - // Destination size will be the next power of two square from the larger width and height... - unsigned width=targa.Header.Width, height=targa.Header.Height; - int ReductionFactor=Get_Reduction(); - int MipLevels=0; - - //Figure out how many mip levels this texture will occupy - for (int i=width, j=height; i > 0 && j > 0; i>>=1, j>>=1) - MipLevels++; - - //Adjust the reduction factor to keep textures above some minimum dimensions - if (MipLevels <= WW3D::Get_Texture_Min_Mip_Levels()) - ReductionFactor=0; - else - { int mipToDrop=MipLevels-WW3D::Get_Texture_Min_Mip_Levels(); - if (ReductionFactor >= mipToDrop) - ReductionFactor=mipToDrop; - } - - width=targa.Header.Width>>ReductionFactor; - height=targa.Header.Height>>ReductionFactor; - unsigned ow = width; - unsigned oh = height; - TextureLoader::Validate_Texture_Size(width, height); - if (width != ow || height != oh) { - WWDEBUG_SAY(("Invalid texture size, scaling required. Texture: %s, size: %d x %d -> %d x %d", Texture->Get_Full_Path(), ow, oh, width, height)); - } - - Width = width; - Height = height; - - // changed because format was being read from previous loading task?! KJM - Format=dest_format; - //if (Format == WW3D_FORMAT_UNKNOWN) { - // Format = Get_Valid_Texture_Format(dest_format, false); - //} else { - // Format = Get_Valid_Texture_Format(Format, false); - //} - - D3DTexture = DX8Wrapper::_Create_DX8_Texture - ( - Width, - Height, - Format, - Texture->MipLevelCount, -#ifdef USE_MANAGED_TEXTURES - D3DPOOL_MANAGED); -#else - D3DPOOL_SYSTEMMEM); -#endif - return true; -} -*/ void TextureLoadTaskClass::Lock_Surfaces() { @@ -1833,12 +1675,8 @@ bool TextureLoadTaskClass::Load_Compressed_Mipmap() unsigned int width = Get_Width(); unsigned int height = Get_Height(); - if (Reduction) - { for (unsigned int level = 0; level < Reduction; ++level) { - width >>= 1; - height >>= 1; - } - } + width >>= Reduction; + height >>= Reduction; for (unsigned int level = 0; level < Get_Mip_Level_Count(); ++level) { @@ -2215,15 +2053,15 @@ void CubeTextureLoadTaskClass::Unlock_Surfaces() bool CubeTextureLoadTaskClass::Begin_Compressed_Load() { - unsigned orig_w,orig_h,orig_d,orig_mip_count,reduction; + unsigned orig_width,orig_height,orig_depth,orig_mip_count,orig_reduction; WW3DFormat orig_format; if (!Get_Texture_Information ( Texture->Get_Full_Path(), - reduction, - orig_w, - orig_h, - orig_d, + orig_reduction, + orig_width, + orig_height, + orig_depth, orig_format, orig_mip_count, true @@ -2234,24 +2072,24 @@ bool CubeTextureLoadTaskClass::Begin_Compressed_Load() } // Destination size will be the next power of two square from the larger width and height... - unsigned int width = orig_w; - unsigned int height = orig_h; - TextureLoader::Validate_Texture_Size(width, height,orig_d); + unsigned int width = orig_width; + unsigned int height = orig_height; + TextureLoader::Validate_Texture_Size(width, height,orig_depth); // If the size doesn't match, try and see if texture reduction would help... (mainly for // cases where loaded texture is larger than hardware limit) - if (width != orig_w || height != orig_h) + if (width != orig_width || height != orig_height) { for (unsigned int i = 1; i < orig_mip_count; ++i) { - unsigned w=orig_w>>i; + unsigned w=orig_width>>i; if (w<4) w=4; - unsigned h=orig_h>>i; + unsigned h=orig_height>>i; if (h<4) h=4; unsigned tmp_w=w; unsigned tmp_h=h; - TextureLoader::Validate_Texture_Size(w,h,orig_d); + TextureLoader::Validate_Texture_Size(w,h,orig_depth); if (w == tmp_w && h == tmp_h) { @@ -2271,13 +2109,13 @@ bool CubeTextureLoadTaskClass::Begin_Compressed_Load() // If texture wants all mip levels, take as many as the file contains (not necessarily all) // Otherwise take as many mip levels as the texture wants, not to exceed the count in file... - if (!mip_level_count) + if (mip_level_count == 0) { - mip_level_count = orig_mip_count;//dds_file.Get_Mip_Level_Count(); + mip_level_count = orig_mip_count; } else if (mip_level_count > orig_mip_count) - {//dds_file.Get_Mip_Level_Count()) { - mip_level_count = orig_mip_count;//dds_file.Get_Mip_Level_Count(); + { + mip_level_count = orig_mip_count; } // Once more, verify that the mip level count is correct (in case it was changed here it might not @@ -2317,15 +2155,15 @@ bool CubeTextureLoadTaskClass::Begin_Compressed_Load() bool CubeTextureLoadTaskClass::Begin_Uncompressed_Load() { - unsigned width,height,depth,orig_mip_count,reduction; + unsigned orig_width,orig_height,orig_depth,orig_mip_count,orig_reduction; WW3DFormat orig_format; if (!Get_Texture_Information ( Texture->Get_Full_Path(), - reduction, - width, - height, - depth, + orig_reduction, + orig_width, + orig_height, + orig_depth, orig_format, orig_mip_count, false @@ -2347,16 +2185,16 @@ bool CubeTextureLoadTaskClass::Begin_Uncompressed_Load() } // Destination size will be the next power of two square from the larger width and height... - unsigned ow = width; - unsigned oh = height; - TextureLoader::Validate_Texture_Size(width, height,depth); - if (width != ow || height != oh) + unsigned ow = orig_width; + unsigned oh = orig_height; + TextureLoader::Validate_Texture_Size(orig_width, orig_height,orig_depth); + if (orig_width != ow || orig_height != oh) { - WWDEBUG_SAY(("Invalid texture size, scaling required. Texture: %s, size: %d x %d -> %d x %d", Texture->Get_Full_Path().str(), ow, oh, width, height)); + WWDEBUG_SAY(("Invalid texture size, scaling required. Texture: %s, size: %d x %d -> %d x %d", Texture->Get_Full_Path().str(), ow, oh, orig_width, orig_height)); } - Width = width; - Height = height; + Width = orig_width; + Height = orig_height; if (Format == WW3D_FORMAT_UNKNOWN) { @@ -2575,15 +2413,15 @@ void VolumeTextureLoadTaskClass::Unlock_Surfaces() bool VolumeTextureLoadTaskClass::Begin_Compressed_Load() { - unsigned orig_w,orig_h,orig_d,orig_mip_count,reduction; + unsigned orig_width,orig_height,orig_depth,orig_mip_count,orig_reduction; WW3DFormat orig_format; if (!Get_Texture_Information ( Texture->Get_Full_Path(), - reduction, - orig_w, - orig_h, - orig_d, + orig_reduction, + orig_width, + orig_height, + orig_depth, orig_format, orig_mip_count, true @@ -2594,22 +2432,22 @@ bool VolumeTextureLoadTaskClass::Begin_Compressed_Load() } // Destination size will be the next power of two square from the larger width and height... - unsigned int width = orig_w; - unsigned int height = orig_h; - unsigned int depth = orig_d; + unsigned int width = orig_width; + unsigned int height = orig_height; + unsigned int depth = orig_depth; TextureLoader::Validate_Texture_Size(width, height, depth); // If the size doesn't match, try and see if texture reduction would help... (mainly for // cases where loaded texture is larger than hardware limit) - if (width != orig_w || height != orig_h || depth != orig_d) + if (width != orig_width || height != orig_height || depth != orig_depth) { for (unsigned int i = 1; i < orig_mip_count; ++i) { - unsigned w=orig_w>>i; + unsigned w=orig_width>>i; if (w<4) w=4; - unsigned h=orig_h>>i; + unsigned h=orig_height>>i; if (h<4) h=4; - unsigned d=orig_d>>i; + unsigned d=orig_depth>>i; if (d<1) d=1; unsigned tmp_w=w; unsigned tmp_h=h; @@ -2637,13 +2475,13 @@ bool VolumeTextureLoadTaskClass::Begin_Compressed_Load() // If texture wants all mip levels, take as many as the file contains (not necessarily all) // Otherwise take as many mip levels as the texture wants, not to exceed the count in file... - if (!mip_level_count) + if (mip_level_count == 0) { - mip_level_count = orig_mip_count;//dds_file.Get_Mip_Level_Count(); + mip_level_count = orig_mip_count; } else if (mip_level_count > orig_mip_count) - {//dds_file.Get_Mip_Level_Count()) { - mip_level_count = orig_mip_count;//dds_file.Get_Mip_Level_Count(); + { + mip_level_count = orig_mip_count; } // Once more, verify that the mip level count is correct (in case it was changed here it might not @@ -2683,15 +2521,15 @@ bool VolumeTextureLoadTaskClass::Begin_Compressed_Load() bool VolumeTextureLoadTaskClass::Begin_Uncompressed_Load() { - unsigned width,height,depth,orig_mip_count,reduction; + unsigned orig_width,orig_height,orig_depth,orig_mip_count,orig_reduction; WW3DFormat orig_format; if (!Get_Texture_Information ( Texture->Get_Full_Path(), - reduction, - width, - height, - depth, + orig_reduction, + orig_width, + orig_height, + orig_depth, orig_format, orig_mip_count, false @@ -2713,18 +2551,18 @@ bool VolumeTextureLoadTaskClass::Begin_Uncompressed_Load() } // Destination size will be the next power of two square from the larger width and height... - unsigned ow = width; - unsigned oh = height; - unsigned od = depth; - TextureLoader::Validate_Texture_Size(width, height, depth); - if (width != ow || height != oh || depth != od) + unsigned ow = orig_width; + unsigned oh = orig_height; + unsigned od = orig_depth; + TextureLoader::Validate_Texture_Size(orig_width, orig_height, orig_depth); + if (orig_width != ow || orig_height != oh || orig_depth != od) { - WWDEBUG_SAY(("Invalid texture size, scaling required. Texture: %s, size: %d x %d -> %d x %d", Texture->Get_Full_Path().str(), ow, oh, width, height)); + WWDEBUG_SAY(("Invalid texture size, scaling required. Texture: %s, size: %d x %d -> %d x %d", Texture->Get_Full_Path().str(), ow, oh, orig_width, orig_height)); } - Width = width; - Height = height; - Depth = depth; + Width = orig_width; + Height = orig_height; + Depth = orig_depth; if (Format == WW3D_FORMAT_UNKNOWN) { From 03b6b936c006bf85d5230b56ee1bd0f7ecaa6a68 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sat, 13 Jun 2026 12:48:57 +0200 Subject: [PATCH 2/3] tweak(textureloader): Remove superfluous texture reduction code from TextureLoadTaskClass::Begin_Uncompressed_Load() (#2789) --- .../Source/WWVegas/WW3D2/textureloader.cpp | 33 ++++--------------- 1 file changed, 6 insertions(+), 27 deletions(-) diff --git a/Core/Libraries/Source/WWVegas/WW3D2/textureloader.cpp b/Core/Libraries/Source/WWVegas/WW3D2/textureloader.cpp index d3c56f57370..78c7d571895 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/textureloader.cpp +++ b/Core/Libraries/Source/WWVegas/WW3D2/textureloader.cpp @@ -1564,18 +1564,7 @@ bool TextureLoadTaskClass::Begin_Uncompressed_Load() Width = orig_width; Height = orig_height; - Reduction = orig_reduction; - - if (!Texture->Is_Reducible() || Texture->MipLevelCount == MIP_LEVELS_1) - Reduction = 0; //app doesn't want this texture to ever be reduced. - else - //Make sure we don't reduce below the level requested by the app - if (Texture->MipLevelCount != MIP_LEVELS_ALL && (Texture->MipLevelCount - Reduction) < 1) - Reduction = Texture->MipLevelCount - 1; - - //Another sanity check - if (Reduction >= orig_mip_count) - Reduction = 0; //should not be possible to get here, but check just in case. + Reduction = 0; if (Format == WW3D_FORMAT_UNKNOWN) { @@ -1586,24 +1575,12 @@ bool TextureLoadTaskClass::Begin_Uncompressed_Load() Format = Get_Valid_Texture_Format(Format, false); } - int reducedWidth=Width; - int reducedHeight=Height; - int reducedMipCount=Texture->MipLevelCount; - - if (Reduction) - { //we don't care about specific levels so reduce them if needed. - reducedWidth >>= Reduction; - reducedHeight >>= Reduction; - if (reducedMipCount != MIP_LEVELS_ALL) - reducedMipCount -= Reduction; - } - D3DTexture = DX8Wrapper::_Create_DX8_Texture ( - reducedWidth, - reducedHeight, + Width, + Height, Format, - (MipCountType)reducedMipCount, + Texture->MipLevelCount, #ifdef USE_MANAGED_TEXTURES D3DPOOL_MANAGED #else @@ -2195,6 +2172,7 @@ bool CubeTextureLoadTaskClass::Begin_Uncompressed_Load() Width = orig_width; Height = orig_height; + Reduction = 0; if (Format == WW3D_FORMAT_UNKNOWN) { @@ -2563,6 +2541,7 @@ bool VolumeTextureLoadTaskClass::Begin_Uncompressed_Load() Width = orig_width; Height = orig_height; Depth = orig_depth; + Reduction = 0; if (Format == WW3D_FORMAT_UNKNOWN) { From 70eb9ccf15dd85760208ab5322e543aa94b08f40 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sat, 13 Jun 2026 13:00:10 +0200 Subject: [PATCH 3/3] bugfix(textureloader): Fix faulty implementations of texture reduction (#2789) --- .../Source/WWVegas/WW3D2/textureloader.cpp | 225 +++++++++--------- 1 file changed, 109 insertions(+), 116 deletions(-) diff --git a/Core/Libraries/Source/WWVegas/WW3D2/textureloader.cpp b/Core/Libraries/Source/WWVegas/WW3D2/textureloader.cpp index 78c7d571895..92f19793e30 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/textureloader.cpp +++ b/Core/Libraries/Source/WWVegas/WW3D2/textureloader.cpp @@ -1389,15 +1389,87 @@ static bool Get_Texture_Information return false; } - w=thumb->Get_Original_Texture_Width() >> reduction; - h=thumb->Get_Original_Texture_Height() >> reduction; - //d=thumb->Get_Original_Texture_Depth() >> reduction; // need to a volume texture support to thumbnails...maybe + w=thumb->Get_Original_Texture_Width(); + h=thumb->Get_Original_Texture_Height(); + d=1; mip_count=thumb->Get_Original_Texture_Mip_Level_Count(); format=thumb->Get_Original_Texture_Format(); + reduction=0; + return true; } +static void Validate_Reduction(const TextureBaseClass* texture, unsigned& reduction, unsigned mip_count) +{ + if (!texture->Is_Reducible() || texture->MipLevelCount == MIP_LEVELS_1) + { + reduction = 0; + } + else if (texture->MipLevelCount != MIP_LEVELS_ALL && reduction >= (unsigned)texture->MipLevelCount) + { + reduction = (unsigned)texture->MipLevelCount - 1; + } + + if (reduction >= mip_count) + { + reduction = 0; // should not be possible, but check just in case. + } +} + + +// If the size doesn't match, try and see if texture reduction would help... +// (mainly for cases where loaded texture is larger than hardware limit) +static void Apply_Reduction(unsigned& width, unsigned& height, unsigned& reduction, unsigned mip_count) +{ + unsigned dummy_depth = 1; + + for (unsigned r = reduction; r < mip_count; ++r) + { + unsigned w = max(width >> r, 4u); + unsigned h = max(height >> r, 4u); + unsigned tmp_w = w; + unsigned tmp_h = h; + + TextureLoader::Validate_Texture_Size(w, h, dummy_depth); + + if (w == tmp_w && h == tmp_h) + { + width = w; + height = h; + reduction = r; + break; + } + } +} + +// If the size doesn't match, try and see if texture reduction would help... +// (mainly for cases where loaded texture is larger than hardware limit) +static void Apply_Reduction_With_Depth(unsigned& width, unsigned& height, unsigned& depth, unsigned& reduction, unsigned mip_count) +{ + for (unsigned r = reduction; r < mip_count; ++r) + { + unsigned w = max(width >> r, 4u); + unsigned h = max(height >> r, 4u); + unsigned d = max(depth >> r, 1u); + unsigned tmp_w = w; + unsigned tmp_h = h; + unsigned tmp_d = d; + + TextureLoader::Validate_Texture_Size(w, h, d); + + if (w == tmp_w && h == tmp_h && d == tmp_d) + { + width = w; + height = h; + depth = d; + reduction = r; + break; + } + } +} + + bool TextureLoadTaskClass::Begin_Compressed_Load() { unsigned orig_width,orig_height,orig_depth,orig_mip_count,orig_reduction; @@ -1419,55 +1491,20 @@ bool TextureLoadTaskClass::Begin_Compressed_Load() } // Destination size will be the next power of two square from the larger width and height... - unsigned int width = orig_width; - unsigned int height = orig_height; - TextureLoader::Validate_Texture_Size(width, height,orig_depth); - - // If the size doesn't match, try and see if texture reduction would help... (mainly for - // cases where loaded texture is larger than hardware limit) - if (width != orig_width || height != orig_height) - { - for (unsigned int i = 1; i < orig_mip_count; ++i) - { - unsigned w=orig_width>>i; - if (w<4) w=4; - unsigned h=orig_height>>i; - if (h<4) h=4; - unsigned tmp_w=w; - unsigned tmp_h=h; + Width = orig_width; + Height = orig_height; + TextureLoader::Validate_Texture_Size(Width, Height, orig_depth); - TextureLoader::Validate_Texture_Size(w,h,orig_depth); + Format = Get_Valid_Texture_Format(orig_format, Texture->Is_Compression_Allowed()); - if (w == tmp_w && h == tmp_h) - { - Reduction += i; - width = w; - height = h; - break; - } - } - } - - Width = width; - Height = height; - Format = Get_Valid_Texture_Format(orig_format, Texture->Is_Compression_Allowed()); Reduction = orig_reduction; + Validate_Reduction(Texture, Reduction, orig_mip_count); - - if (!Texture->Is_Reducible() || Texture->MipLevelCount == MIP_LEVELS_1) - Reduction = 0; //app doesn't want this texture to ever be reduced. - else - //Make sure we don't reduce below the level requested by the app - if (Texture->MipLevelCount != MIP_LEVELS_ALL && (Texture->MipLevelCount - Reduction) < 1) - Reduction = Texture->MipLevelCount - 1; - - //Another sanity check - if (Reduction >= orig_mip_count) - Reduction = 0; //should not be possible to get here, but check just in case. + unsigned reduced_width = orig_width; + unsigned reduced_height = orig_height; + Apply_Reduction(reduced_width, reduced_height, Reduction, orig_mip_count); unsigned int mip_level_count = Get_Mip_Level_Count(); - int reduced_width = Width >> Reduction; - int reduced_height = Height >> Reduction; // If texture wants all mip levels, take as many as the file contains (not necessarily all) // Otherwise take as many mip levels as the texture wants, not to exceed the count in file... @@ -2049,38 +2086,18 @@ bool CubeTextureLoadTaskClass::Begin_Compressed_Load() } // Destination size will be the next power of two square from the larger width and height... - unsigned int width = orig_width; - unsigned int height = orig_height; - TextureLoader::Validate_Texture_Size(width, height,orig_depth); + Width = orig_width; + Height = orig_height; + TextureLoader::Validate_Texture_Size(Width, Height, orig_depth); - // If the size doesn't match, try and see if texture reduction would help... (mainly for - // cases where loaded texture is larger than hardware limit) - if (width != orig_width || height != orig_height) - { - for (unsigned int i = 1; i < orig_mip_count; ++i) - { - unsigned w=orig_width>>i; - if (w<4) w=4; - unsigned h=orig_height>>i; - if (h<4) h=4; - unsigned tmp_w=w; - unsigned tmp_h=h; - - TextureLoader::Validate_Texture_Size(w,h,orig_depth); + Format = Get_Valid_Texture_Format(orig_format, Texture->Is_Compression_Allowed()); - if (w == tmp_w && h == tmp_h) - { - Reduction += i; - width = w; - height = h; - break; - } - } - } + Reduction = orig_reduction; + Validate_Reduction(Texture, Reduction, orig_mip_count); - Width = width; - Height = height; - Format = Get_Valid_Texture_Format(orig_format, Texture->Is_Compression_Allowed()); + unsigned reduced_width = orig_width; + unsigned reduced_height = orig_height; + Apply_Reduction(reduced_width, reduced_height, Reduction, orig_mip_count); unsigned int mip_level_count = Get_Mip_Level_Count(); @@ -2115,8 +2132,8 @@ bool CubeTextureLoadTaskClass::Begin_Compressed_Load() D3DTexture = DX8Wrapper::_Create_DX8_Cube_Texture ( - Width, - Height, + reduced_width, + reduced_height, Format, (MipCountType)mip_level_count, #ifdef USE_MANAGED_TEXTURES @@ -2410,44 +2427,20 @@ bool VolumeTextureLoadTaskClass::Begin_Compressed_Load() } // Destination size will be the next power of two square from the larger width and height... - unsigned int width = orig_width; - unsigned int height = orig_height; - unsigned int depth = orig_depth; - TextureLoader::Validate_Texture_Size(width, height, depth); + Width = orig_width; + Height = orig_height; + Depth = orig_depth; + TextureLoader::Validate_Texture_Size(Width, Height, Depth); - // If the size doesn't match, try and see if texture reduction would help... (mainly for - // cases where loaded texture is larger than hardware limit) - if (width != orig_width || height != orig_height || depth != orig_depth) - { - for (unsigned int i = 1; i < orig_mip_count; ++i) - { - unsigned w=orig_width>>i; - if (w<4) w=4; - unsigned h=orig_height>>i; - if (h<4) h=4; - unsigned d=orig_depth>>i; - if (d<1) d=1; - unsigned tmp_w=w; - unsigned tmp_h=h; - unsigned tmp_d=d; - - TextureLoader::Validate_Texture_Size(w,h,d); - - if (w == tmp_w && h == tmp_h && d== tmp_d) - { - Reduction += i; - width = w; - height = h; - depth = d; - break; - } - } - } + Format = Get_Valid_Texture_Format(orig_format, Texture->Is_Compression_Allowed()); - Width = width; - Height = height; - Depth = depth; - Format = Get_Valid_Texture_Format(orig_format, Texture->Is_Compression_Allowed()); + Reduction = orig_reduction; + Validate_Reduction(Texture, Reduction, orig_mip_count); + + unsigned reduced_width = orig_width; + unsigned reduced_height = orig_height; + unsigned reduced_depth = orig_depth; + Apply_Reduction_With_Depth(reduced_width, reduced_height, reduced_depth, Reduction, orig_mip_count); unsigned int mip_level_count = Get_Mip_Level_Count(); @@ -2481,9 +2474,9 @@ bool VolumeTextureLoadTaskClass::Begin_Compressed_Load() D3DTexture = DX8Wrapper::_Create_DX8_Volume_Texture ( - Width, - Height, - Depth, + reduced_width, + reduced_height, + reduced_depth, Format, (MipCountType)mip_level_count, #ifdef USE_MANAGED_TEXTURES