Adding initial support for user-provided mipmaps. This isn't hooked up to the command line tool or the JS wrappers yet.
diff --git a/encoder/basisu_comp.cpp b/encoder/basisu_comp.cpp index 0e57a4c..e9c9d1a 100644 --- a/encoder/basisu_comp.cpp +++ b/encoder/basisu_comp.cpp
@@ -71,8 +71,16 @@ debug_printf("Has global selector codebook: %i\n", m_params.m_pSel_codebook != nullptr); - debug_printf("Source images: %u, source filenames: %u, source alpha filenames: %i\n", - (uint32_t)m_params.m_source_images.size(), (uint32_t)m_params.m_source_filenames.size(), (uint32_t)m_params.m_source_alpha_filenames.size()); + debug_printf("Source images: %u, source filenames: %u, source alpha filenames: %i, Source mipmap images: %u\n", + m_params.m_source_images.size(), m_params.m_source_filenames.size(), m_params.m_source_alpha_filenames.size(), m_params.m_source_mipmap_images.size()); + + if (m_params.m_source_mipmap_images.size()) + { + debug_printf("m_source_mipmap_images array sizes:\n"); + for (uint32_t i = 0; i < m_params.m_source_mipmap_images.size(); i++) + debug_printf("%u ", m_params.m_source_mipmap_images[i].size()); + debug_printf("\n"); + } PRINT_BOOL_VALUE(m_uastc); PRINT_BOOL_VALUE(m_y_flip); @@ -540,7 +548,7 @@ debug_printf("Resampling to %ix%i\n", new_width, new_height); - // TODO: A box filter - kaiser looks too sharp on video. + // TODO: A box filter - kaiser looks too sharp on video. Let the caller control this. image temp_img(new_width, new_height); image_resample(file_image, temp_img, m_params.m_perceptual, "box"); // "kaiser"); temp_img.swap(file_image); @@ -562,6 +570,39 @@ source_filenames.push_back(pSource_filename); } + // Check if the caller has generated their own mipmaps. + if (m_params.m_source_mipmap_images.size()) + { + // Make sure they've passed us enough mipmap chains. + if ((m_params.m_source_images.size() != m_params.m_source_mipmap_images.size()) || (total_source_files != m_params.m_source_images.size())) + { + error_printf("basis_compressor::read_source_images(): m_params.m_source_mipmap_images.size() must equal m_params.m_source_images.size()!\n"); + return false; + } + + // Check if any of the user-supplied mipmap levels has alpha. + // We're assuming the user has already preswizzled their mipmap source images. + if (!m_any_source_image_has_alpha) + { + for (uint32_t source_file_index = 0; source_file_index < total_source_files; source_file_index++) + { + for (uint32_t mip_index = 0; mip_index < m_params.m_source_mipmap_images[source_file_index].size(); mip_index++) + { + const image& mip_img = m_params.m_source_mipmap_images[source_file_index][mip_index]; + + if (mip_img.has_alpha()) + { + m_any_source_image_has_alpha = true; + break; + } + } + + if (m_any_source_image_has_alpha) + break; + } + } + } + debug_printf("Any source image has alpha: %u\n", m_any_source_image_has_alpha); for (uint32_t source_file_index = 0; source_file_index < total_source_files; source_file_index++) @@ -573,10 +614,22 @@ basisu::vector<image> slices; slices.reserve(32); + + // The first (largest) mipmap level. slices.push_back(file_image); - - if (m_params.m_mip_gen) + + if (m_params.m_source_mipmap_images.size()) { + // User-provided mipmaps for each layer or image in the texture array. + for (uint32_t mip_index = 0; mip_index < m_params.m_source_mipmap_images[source_file_index].size(); mip_index++) + { + const image& mip_img = m_params.m_source_mipmap_images[source_file_index][mip_index]; + slices.push_back(mip_img); + } + } + else if (m_params.m_mip_gen) + { + // Automatically generate mipmaps. if (!generate_mipmaps(file_image, slices, m_any_source_image_has_alpha)) return false; }
diff --git a/encoder/basisu_comp.h b/encoder/basisu_comp.h index fd8a913..1964565 100644 --- a/encoder/basisu_comp.h +++ b/encoder/basisu_comp.h
@@ -241,6 +241,7 @@ m_source_alpha_filenames.clear(); m_source_images.clear(); + m_source_mipmap_images.clear(); m_out_filename.clear(); @@ -329,7 +330,11 @@ basisu::vector<std::string> m_source_alpha_filenames; basisu::vector<image> m_source_images; - // TODO: Allow caller to supply their own mipmaps + + // Stores mipmaps starting from level 1. Level 0 is still stored in m_source_images, as usual. + // If m_source_mipmaps isn't empty, automatic mipmap generation isn't done. m_source_mipmaps.size() MUST equal m_source_images.size() or the compressor returns an error. + // Note the compressor doesn't apply the user-provided swizzling (in m_swizzle), or any other preprocessing, to these images. + basisu::vector< basisu::vector<image> > m_source_mipmap_images; // Filename of the output basis file std::string m_out_filename;
diff --git a/webgl/encoder/build/basis_encoder.wasm b/webgl/encoder/build/basis_encoder.wasm index 379d4a9..e64b734 100644 --- a/webgl/encoder/build/basis_encoder.wasm +++ b/webgl/encoder/build/basis_encoder.wasm Binary files differ