From 6c973af60d8cd68bcf220ca812d62513afabdb22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tur=C3=A1nszki=20J=C3=A1nos?= Date: Sat, 28 Jun 2025 08:36:27 +0200 Subject: [PATCH] block compressed texture saving fix for non block-aligned dimensions --- WickedEngine/wiGraphics.h | 12 ++++++------ WickedEngine/wiHelper.cpp | 21 +++++++++------------ WickedEngine/wiVersion.cpp | 2 +- 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/WickedEngine/wiGraphics.h b/WickedEngine/wiGraphics.h index 1c605fba5..bfe90e47f 100644 --- a/WickedEngine/wiGraphics.h +++ b/WickedEngine/wiGraphics.h @@ -1882,17 +1882,17 @@ namespace wi::graphics size_t size = 0; const uint32_t bytes_per_block = GetFormatStride(desc.format); const uint32_t pixels_per_block = GetFormatBlockSize(desc.format); - const uint32_t num_blocks_x = desc.width / pixels_per_block; - const uint32_t num_blocks_y = desc.height / pixels_per_block; const uint32_t mips = desc.mip_levels == 0 ? GetMipCount(desc.width, desc.height, desc.depth) : desc.mip_levels; for (uint32_t layer = 0; layer < desc.array_size; ++layer) { for (uint32_t mip = 0; mip < mips; ++mip) { - const uint32_t width = std::max(1u, num_blocks_x >> mip); - const uint32_t height = std::max(1u, num_blocks_y >> mip); - const uint32_t depth = std::max(1u, desc.depth >> mip); - size += width * height * depth * bytes_per_block; + const uint32_t mip_width = std::max(1u, desc.width >> mip); + const uint32_t mip_height = std::max(1u, desc.height >> mip); + const uint32_t mip_depth = std::max(1u, desc.depth >> mip); + const uint32_t num_blocks_x = (mip_width + pixels_per_block - 1) / pixels_per_block; + const uint32_t num_blocks_y = (mip_height + pixels_per_block - 1) / pixels_per_block; + size += num_blocks_x * num_blocks_y * mip_depth * bytes_per_block; } } size *= desc.sample_count; diff --git a/WickedEngine/wiHelper.cpp b/WickedEngine/wiHelper.cpp index 03b32a64d..9b425b1ea 100644 --- a/WickedEngine/wiHelper.cpp +++ b/WickedEngine/wiHelper.cpp @@ -156,25 +156,26 @@ namespace wi::helper const uint32_t data_stride = GetFormatStride(desc.format); const uint32_t block_size = GetFormatBlockSize(desc.format); - const uint32_t num_blocks_x = desc.width / block_size; - const uint32_t num_blocks_y = desc.height / block_size; size_t cpy_offset = 0; size_t subresourceIndex = 0; for (uint32_t layer = 0; layer < desc.array_size; ++layer) { - uint32_t mip_width = num_blocks_x; - uint32_t mip_height = num_blocks_y; - uint32_t mip_depth = desc.depth; for (uint32_t mip = 0; mip < desc.mip_levels; ++mip) { + const uint32_t mip_width = std::max(1u, desc.width >> mip); + const uint32_t mip_height = std::max(1u, desc.height >> mip); + const uint32_t mip_depth = std::max(1u, desc.depth >> mip); + const uint32_t num_blocks_x = (mip_width + block_size - 1) / block_size; + const uint32_t num_blocks_y = (mip_height + block_size - 1) / block_size; + assert(subresourceIndex < stagingTex.mapped_subresource_count); const SubresourceData& subresourcedata = stagingTex.mapped_subresources[subresourceIndex++]; - const size_t dst_rowpitch = mip_width * data_stride; + const size_t dst_rowpitch = num_blocks_x * data_stride; for (uint32_t z = 0; z < mip_depth; ++z) { uint8_t* dst_slice = texturedata.data() + cpy_offset; uint8_t* src_slice = (uint8_t*)subresourcedata.data_ptr + subresourcedata.slice_pitch * z; - for (uint32_t i = 0; i < mip_height; ++i) + for (uint32_t i = 0; i < num_blocks_y; ++i) { std::memcpy( dst_slice + i * dst_rowpitch, @@ -182,12 +183,8 @@ namespace wi::helper dst_rowpitch ); } - cpy_offset += mip_height * dst_rowpitch; + cpy_offset += num_blocks_y * dst_rowpitch; } - - mip_width = std::max(1u, mip_width / 2); - mip_height = std::max(1u, mip_height / 2); - mip_depth = std::max(1u, mip_depth / 2); } } } diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 110a3e4eb..c54e3f072 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wi::version // minor features, major updates, breaking compatibility changes const int minor = 71; // minor bug fixes, alterations, refactors, updates - const int revision = 799; + const int revision = 800; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);