Răsfoiți Sursa

Fix silly multiple uncompress&recompress when generating mips for compressed texture

rdb 9 ani în urmă
părinte
comite
d50a326ca7

+ 5 - 0
panda/src/egg2pg/eggLoader.cxx

@@ -950,6 +950,11 @@ load_texture(TextureDef &def, EggTexture *egg_tex) {
     }
   }
 
+  // Allow the texture loader to pre-compress the texture.
+  if (egg_tex->get_compression_mode() == EggTexture::CM_on) {
+    options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_allow_compression);
+  }
+
   PT(Texture) tex;
   switch (egg_tex->get_texture_type()) {
   case EggTexture::TT_unspecified:

+ 0 - 7
panda/src/gobj/config_gobj.cxx

@@ -112,13 +112,6 @@ ConfigVariableBool keep_texture_ram
           "texture image from disk; but it will consume memory somewhat "
           "wastefully."));
 
-ConfigVariableBool compressed_textures
-("compressed-textures", false,
- PRC_DESC("Set this to true to compress textures as they are loaded into "
-          "texture memory, if the driver supports this.  Specifically, this "
-          "changes the meaning of set_compression(Texture::CM_default) to "
-          "Texture::CM_on."));
-
 ConfigVariableBool driver_compress_textures
 ("driver-compress-textures", false,
  PRC_DESC("Set this true to ask the graphics driver to compress textures, "

+ 0 - 1
panda/src/gobj/config_gobj.h

@@ -36,7 +36,6 @@ extern EXPCL_PANDA_GOBJ ConfigVariableList exclude_texture_scale;
 
 
 extern EXPCL_PANDA_GOBJ ConfigVariableBool keep_texture_ram;
-extern EXPCL_PANDA_GOBJ ConfigVariableBool compressed_textures;
 extern EXPCL_PANDA_GOBJ ConfigVariableBool driver_compress_textures;
 extern EXPCL_PANDA_GOBJ ConfigVariableBool driver_generate_mipmaps;
 extern EXPCL_PANDA_GOBJ ConfigVariableBool vertex_buffers;

+ 5 - 2
panda/src/gobj/texture.I

@@ -1678,9 +1678,12 @@ clear_ram_mipmap_images() {
  */
 INLINE void Texture::
 generate_ram_mipmap_images() {
-  CDWriter cdata(_cycler, unlocked_ensure_ram_image(false));
+  // Don't use unlocked_ensure_ram_image here, because
+  // do_generate_ram_mipmap_images will want to decompress and recompress the
+  // image itself.
+  CDWriter cdata(_cycler, false);
   cdata->inc_image_modified();
-  do_generate_ram_mipmap_images(cdata);
+  do_generate_ram_mipmap_images(cdata, true);
 }
 
 /**

+ 21 - 8
panda/src/gobj/texture.cxx

@@ -2708,7 +2708,8 @@ do_read(CData *cdata, const Filename &fullpath, const Filename &alpha_fullpath,
       // If we intend to keep the ram image around, consider compressing it
       // etc.
       bool generate_mipmaps = ((options.get_texture_flags() & LoaderOptions::TF_generate_mipmaps) != 0);
-      do_consider_auto_process_ram_image(cdata, generate_mipmaps || uses_mipmaps(), true);
+      bool allow_compression = ((options.get_texture_flags() & LoaderOptions::TF_allow_compression) != 0);
+      do_consider_auto_process_ram_image(cdata, generate_mipmaps || uses_mipmaps(), allow_compression);
     }
   }
 
@@ -4277,7 +4278,12 @@ do_reload_ram_image(CData *cdata, bool allow_compression) {
   int orig_num_components = cdata->_num_components;
 
   LoaderOptions options;
-  options.set_texture_flags(LoaderOptions::TF_preload);
+  if (allow_compression) {
+    options.set_texture_flags(LoaderOptions::TF_preload |
+                              LoaderOptions::TF_allow_compression);
+  } else {
+    options.set_texture_flags(LoaderOptions::TF_preload);
+  }
   do_read(cdata, cdata->_fullpath, cdata->_alpha_fullpath,
           cdata->_primary_file_num_channels, cdata->_alpha_file_channel,
           z, n, cdata->_has_read_pages, cdata->_has_read_mipmaps, options, NULL);
@@ -4618,7 +4624,7 @@ do_consider_auto_process_ram_image(CData *cdata, bool generate_mipmaps,
 
   if (generate_mipmaps && !driver_generate_mipmaps &&
       cdata->_ram_images.size() == 1) {
-    do_generate_ram_mipmap_images(cdata);
+    do_generate_ram_mipmap_images(cdata, false);
     modified = true;
   }
 
@@ -4725,7 +4731,7 @@ do_compress_ram_image(CData *cdata, Texture::CompressionMode compression,
     if (!do_has_all_ram_mipmap_images(cdata)) {
       // If we're about to compress the RAM image, we should ensure that we
       // have all of the mipmap levels first.
-      do_generate_ram_mipmap_images(cdata);
+      do_generate_ram_mipmap_images(cdata, false);
     }
 
     RamImages compressed_ram_images;
@@ -6334,10 +6340,12 @@ do_clear_ram_mipmap_images(CData *cdata) {
 }
 
 /**
- *
+ * Generates the RAM mipmap images for this texture, first uncompressing it as
+ * required.  Will recompress the image if it was originally compressed,
+ * unless allow_recompress is true.
  */
 void Texture::
-do_generate_ram_mipmap_images(CData *cdata) {
+do_generate_ram_mipmap_images(CData *cdata, bool allow_recompress) {
   nassertv(do_has_ram_image(cdata));
 
   if (do_get_expected_num_mipmap_levels(cdata) == 1) {
@@ -6399,7 +6407,7 @@ do_generate_ram_mipmap_images(CData *cdata) {
     }
   }
 
-  if (orig_compression_mode != CM_off) {
+  if (orig_compression_mode != CM_off && allow_recompress) {
     // Now attempt to recompress the mipmap images according to the original
     // compression mode.  We don't need to bother compressing the first image
     // (it was already compressed, after all), so temporarily remove it from
@@ -6418,6 +6426,11 @@ do_generate_ram_mipmap_images(CData *cdata) {
     bool success = do_compress_ram_image(cdata, orig_compression_mode, QL_default, NULL);
     // Now restore the toplevel image.
     if (success) {
+      if (gobj_cat.is_debug()) {
+        gobj_cat.debug()
+          << "Compressed " << get_name() << " generated mipmaps with "
+          << cdata->_ram_image_compression << "\n";
+      }
       cdata->_ram_images.insert(cdata->_ram_images.begin(), orig_compressed_image);
     } else {
       cdata->_ram_images.insert(cdata->_ram_images.begin(), uncompressed_image);
@@ -8255,7 +8268,7 @@ do_squish(CData *cdata, Texture::CompressionMode compression, int squish_flags)
   if (!do_has_all_ram_mipmap_images(cdata)) {
     // If we're about to compress the RAM image, we should ensure that we have
     // all of the mipmap levels first.
-    do_generate_ram_mipmap_images(cdata);
+    do_generate_ram_mipmap_images(cdata, false);
   }
 
   RamImages compressed_ram_images;

+ 1 - 1
panda/src/gobj/texture.h

@@ -697,7 +697,7 @@ protected:
   INLINE void do_clear_ram_image(CData *cdata);
   void do_clear_simple_ram_image(CData *cdata);
   void do_clear_ram_mipmap_images(CData *cdata);
-  void do_generate_ram_mipmap_images(CData *cdata);
+  void do_generate_ram_mipmap_images(CData *cdata, bool allow_recompress);
   void do_set_pad_size(CData *cdata, int x, int y, int z);
   virtual bool do_can_reload(const CData *cdata) const;
   bool do_reload(CData *cdata);

+ 7 - 0
panda/src/putil/config_util.cxx

@@ -143,6 +143,13 @@ ConfigVariableBool preload_simple_textures
           "in a sub-thread.  It's not generally necessary if you are "
           "loading bam files that were generated via egg2bam."));
 
+ConfigVariableBool compressed_textures
+("compressed-textures", false,
+ PRC_DESC("Set this to true to compress textures as they are loaded into "
+          "texture memory, if the driver supports this.  Specifically, this "
+          "changes the meaning of set_compression(Texture::CM_default) to "
+          "Texture::CM_on."));
+
 ConfigVariableBool cache_check_timestamps
 ("cache-check-timestamps", true,
  PRC_DESC("Set this true to check the timestamps on disk (when possible) "

+ 1 - 0
panda/src/putil/config_util.h

@@ -46,6 +46,7 @@ extern ConfigVariableDouble sleep_precision;
 
 extern EXPCL_PANDA_PUTIL ConfigVariableBool preload_textures;
 extern EXPCL_PANDA_PUTIL ConfigVariableBool preload_simple_textures;
+extern EXPCL_PANDA_PUTIL ConfigVariableBool compressed_textures;
 extern EXPCL_PANDA_PUTIL ConfigVariableBool cache_check_timestamps;
 
 extern EXPCL_PANDA_PUTIL void init_libputil();

+ 8 - 0
panda/src/putil/loaderOptions.cxx

@@ -28,12 +28,16 @@ LoaderOptions(int flags) :
   // Shadowing the variables in config_util for static init ordering issues.
   static ConfigVariableBool *preload_textures;
   static ConfigVariableBool *preload_simple_textures;
+  static ConfigVariableBool *compressed_textures;
   if (preload_textures == NULL) {
     preload_textures = new ConfigVariableBool("preload-textures", true);
   }
   if (preload_simple_textures == NULL) {
     preload_simple_textures = new ConfigVariableBool("preload-simple-textures", false);
   }
+  if (compressed_textures == NULL) {
+    compressed_textures = new ConfigVariableBool("compressed-textures", false);
+  }
 
   if (*preload_textures) {
     _texture_flags |= TF_preload;
@@ -41,6 +45,9 @@ LoaderOptions(int flags) :
   if (*preload_simple_textures) {
     _texture_flags |= TF_preload_simple;
   }
+  if (*compressed_textures) {
+    _texture_flags |= TF_allow_compression;
+  }
 }
 
 /**
@@ -77,6 +84,7 @@ output(ostream &out) const {
   write_texture_flag(out, sep, "TF_preload_simple", TF_preload_simple);
   write_texture_flag(out, sep, "TF_allow_1d", TF_allow_1d);
   write_texture_flag(out, sep, "TF_generate_mipmaps", TF_generate_mipmaps);
+  write_texture_flag(out, sep, "TF_allow_compression", TF_allow_compression);
   if (sep.empty()) {
     out << "0";
   }

+ 1 - 0
panda/src/putil/loaderOptions.h

@@ -45,6 +45,7 @@ PUBLISHED:
     TF_multiview         = 0x0040,  // Load a multiview texture in pages
     TF_integer           = 0x0080,  // Load as an integer (RGB) texture
     TF_float             = 0x0100,  // Load as a floating-point (depth) texture
+    TF_allow_compression = 0x0200,  // Consider compressing RAM image
   };
 
   LoaderOptions(int flags = LF_search | LF_report_errors);