Browse Source

glgsg: Use glClearTexImage even when tex has no storage

Just use glTexImage with null image to create the storage first, then
clear it, this prevents needlessly generating a filled RAM image on the
CPU
rdb 10 months ago
parent
commit
e681c17215
1 changed files with 30 additions and 17 deletions
  1. 30 17
      panda/src/glstuff/glGraphicsStateGuardian_src.cxx

+ 30 - 17
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -14675,6 +14675,11 @@ upload_texture_view(CLP(TextureContext) *gtc, int view, bool needs_reload,
         << "loading new texture object for " << tex->get_name() << " view "
         << "loading new texture object for " << tex->get_name() << " view "
         << view << ", " << width << " x " << height << " x " << depth
         << view << ", " << width << " x " << height << " x " << depth
         << ", mipmaps " << num_ram_mipmap_levels << " / " << num_levels;
         << ", mipmaps " << num_ram_mipmap_levels << " / " << num_levels;
+
+      if (num_ram_mipmap_levels == 0 && tex->has_clear_color()) {
+        GLCAT.debug(false)
+          << ", clearing to " << tex->get_clear_color();
+      }
     }
     }
     else {
     else {
       // Try to subload the image over the existing GL Texture object, possibly
       // Try to subload the image over the existing GL Texture object, possibly
@@ -14758,28 +14763,36 @@ upload_texture_view(CLP(TextureContext) *gtc, int view, bool needs_reload,
         // level to a solid color.
         // level to a solid color.
 #ifndef OPENGLES
 #ifndef OPENGLES
         if (target != GL_TEXTURE_BUFFER) {
         if (target != GL_TEXTURE_BUFFER) {
-          if (_supports_clear_texture && !needs_reload) {
-            // We can do that with the convenient glClearTexImage
-            // function.
-            vector_uchar clear_data = tex->get_clear_data();
-
-            if (pages.has_all_of(0, depth)) {
-              _glClearTexImage(index, level, external_format,
-                               component_type, (void *)&clear_data[0]);
-            }
-            else for (size_t sri = 0; sri < pages.get_num_subranges(); ++sri) {
-              int begin = pages.get_subrange_begin(sri);
-              int num_pages = pages.get_subrange_end(sri) - begin;
-              _glClearTexSubImage(index, level, 0, 0, begin,
-                                  width, height, num_pages, external_format,
-                                  component_type, (void *)&clear_data[0]);
+          if (_supports_clear_texture && !compressed) {
+            // If we don't have storage, we create it with a NULL image first.
+            if (!needs_reload ||
+                upload_texture_level(true, false, target, level,
+                                     width, height, depth, internal_format,
+                                     external_format, component_type,
+                                     nullptr, 0, pages, usage)) {
+              vector_uchar clear_data = tex->get_clear_data();
+
+              if (needs_reload || pages.has_all_of(0, depth)) {
+                _glClearTexImage(index, level, external_format,
+                                 component_type, (void *)&clear_data[0]);
+              }
+              else for (size_t sri = 0; sri < pages.get_num_subranges(); ++sri) {
+                int begin = pages.get_subrange_begin(sri);
+                int num_pages = pages.get_subrange_end(sri) - begin;
+                _glClearTexSubImage(index, level, 0, 0, begin,
+                                    width, height, num_pages, external_format,
+                                    component_type, (void *)&clear_data[0]);
+              }
+              continue;
             }
             }
-            continue;
           }
           }
         } else {
         } else {
-          if (_supports_clear_buffer && !needs_reload) {
+          if (_supports_clear_buffer) {
             // For buffer textures we need to clear the underlying
             // For buffer textures we need to clear the underlying
             // storage.
             // storage.
+            if (needs_reload) {
+              _glBufferData(GL_TEXTURE_BUFFER, tex->get_expected_ram_mipmap_view_size(n), nullptr, usage);
+            }
             vector_uchar clear_data = tex->get_clear_data();
             vector_uchar clear_data = tex->get_clear_data();
 
 
             _glClearBufferData(GL_TEXTURE_BUFFER, internal_format, external_format,
             _glClearBufferData(GL_TEXTURE_BUFFER, internal_format, external_format,