[Bf-blender-cvs] [d626ced6f1f] master: GPU: Estimate a better value for the memory used

Germano Cavalcante noreply at git.blender.org
Tue Mar 24 16:13:44 CET 2020


Commit: d626ced6f1fe8284737aecdabe70b48a42563b75
Author: Germano Cavalcante
Date:   Tue Mar 24 12:09:39 2020 -0300
Branches: master
https://developer.blender.org/rBd626ced6f1fe8284737aecdabe70b48a42563b75

GPU: Estimate a better value for the memory used

This commit adds a `mipmaps` member to the `GPUTexture` struct and also
computes to the memory used by these mipmaps and the memory used for
textures that are created from an external bindcode.

So it solves the following inconsistencies:
- The memory value for mipmaps was not being computed.
- As `GPU_texture_from_bindcode` didn't call
 `gpu_texture_memory_footprint_add`, it brought inconsistencies to the
 value of the used memory, especially when the texture is freed.

Differential Revision: https://developer.blender.org/D3554

===================================================================

M	source/blender/gpu/intern/gpu_texture.c

===================================================================

diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c
index 088cf912d6a..a2afac0580e 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.c
@@ -82,7 +82,7 @@ struct GPUTexture {
   eGPUTextureFormat format;
   eGPUTextureFormatFlag format_flag;
 
-  uint bytesize;  /* number of byte for one pixel */
+  int mipmaps;    /* number of mipmaps */
   int components; /* number of color/alpha channels */
   int samples;    /* number of samples for multisamples textures. 0 if not multisample target */
 
@@ -90,6 +90,8 @@ struct GPUTexture {
   GPUFrameBuffer *fb[GPU_TEX_MAX_FBO_ATTACHED];
 };
 
+static uint gpu_get_bytesize(eGPUTextureFormat data_type);
+
 /* ------ Memory Management ------- */
 /* Records every texture allocation / free
  * to estimate the Texture Pool Memory consumption */
@@ -97,23 +99,39 @@ static uint memory_usage;
 
 static uint gpu_texture_memory_footprint_compute(GPUTexture *tex)
 {
-  int samp = max_ii(tex->samples, 1);
+  uint memsize;
+  const uint bytesize = gpu_get_bytesize(tex->format);
+  const int samp = max_ii(tex->samples, 1);
   switch (tex->target_base) {
     case GL_TEXTURE_1D:
-      return tex->bytesize * tex->w * samp;
+    case GL_TEXTURE_BUFFER:
+      memsize = bytesize * tex->w * samp;
+      break;
     case GL_TEXTURE_1D_ARRAY:
     case GL_TEXTURE_2D:
-      return tex->bytesize * tex->w * tex->h * samp;
+      memsize = bytesize * tex->w * tex->h * samp;
+      break;
     case GL_TEXTURE_2D_ARRAY:
     case GL_TEXTURE_3D:
-      return tex->bytesize * tex->w * tex->h * tex->d * samp;
+      memsize = bytesize * tex->w * tex->h * tex->d * samp;
+      break;
     case GL_TEXTURE_CUBE_MAP:
-      return tex->bytesize * 6 * tex->w * tex->h * samp;
+      memsize = bytesize * 6 * tex->w * tex->h * samp;
+      break;
     case GL_TEXTURE_CUBE_MAP_ARRAY_ARB:
-      return tex->bytesize * 6 * tex->w * tex->h * tex->d * samp;
+      memsize = bytesize * 6 * tex->w * tex->h * tex->d * samp;
+      break;
     default:
+      BLI_assert(0);
       return 0;
   }
+  if (tex->mipmaps != 0) {
+    /* Just to get an idea of the memory used here is computed
+     * as if the maximum number of mipmaps was generated. */
+    memsize += memsize / 3;
+  }
+
+  return memsize;
 }
 
 static void gpu_texture_memory_footprint_add(GPUTexture *tex)
@@ -362,7 +380,7 @@ static uint gpu_get_bytesize(eGPUTextureFormat data_type)
       return 16;
     case GPU_RGB16F:
       return 12;
-    case GPU_DEPTH32F_STENCIL8:
+    case GPU_DEPTH32F_STENCIL8: /* 32-bit depth, 8 bits stencil, and 24 unused bits. */
       return 8;
     case GPU_RG16F:
     case GPU_RG16I:
@@ -396,65 +414,84 @@ static uint gpu_get_bytesize(eGPUTextureFormat data_type)
   }
 }
 
-static GLenum gpu_get_gl_internalformat(eGPUTextureFormat format)
+static GLenum gpu_format_to_gl_internalformat(eGPUTextureFormat format)
 {
   /* You can add any of the available type to this list
    * For available types see GPU_texture.h */
   switch (format) {
     /* Formats texture & renderbuffer */
+    case GPU_RGBA8UI:
+      return GL_RGBA8UI;
+    case GPU_RGBA8I:
+      return GL_RGBA8I;
+    case GPU_RGBA8:
+      return GL_RGBA8;
+    case GPU_RGBA32UI:
+      return GL_RGBA32UI;
+    case GPU_RGBA32I:
+      return GL_RGBA32I;
     case GPU_RGBA32F:
       return GL_RGBA32F;
+    case GPU_RGBA16UI:
+      return GL_RGBA16UI;
+    case GPU_RGBA16I:
+      return GL_RGBA16I;
     case GPU_RGBA16F:
       return GL_RGBA16F;
     case GPU_RGBA16:
       return GL_RGBA16;
+    case GPU_RG8UI:
+      return GL_RG8UI;
+    case GPU_RG8I:
+      return GL_RG8I;
+    case GPU_RG8:
+      return GL_RG8;
+    case GPU_RG32UI:
+      return GL_RG32UI;
+    case GPU_RG32I:
+      return GL_RG32I;
     case GPU_RG32F:
       return GL_RG32F;
-    case GPU_RGB16F:
-      return GL_RGB16F;
-    case GPU_RG16F:
-      return GL_RG16F;
+    case GPU_RG16UI:
+      return GL_RG16UI;
     case GPU_RG16I:
       return GL_RG16I;
+    case GPU_RG16F:
+      return GL_RGBA32F;
     case GPU_RG16:
       return GL_RG16;
-    case GPU_RGBA8:
-      return GL_RGBA8;
-    case GPU_RGBA8UI:
-      return GL_RGBA8UI;
-    case GPU_SRGB8_A8:
-      return GL_SRGB8_ALPHA8;
-    case GPU_R32F:
-      return GL_R32F;
+    case GPU_R8UI:
+      return GL_R8UI;
+    case GPU_R8I:
+      GL_R8I;
+    case GPU_R8:
+      return GL_R8;
     case GPU_R32UI:
       return GL_R32UI;
     case GPU_R32I:
       return GL_R32I;
-    case GPU_R16F:
-      return GL_R16F;
-    case GPU_R16I:
-      return GL_R16I;
+    case GPU_R32F:
+      return GL_R32F;
     case GPU_R16UI:
       return GL_R16UI;
-    case GPU_RG8:
-      return GL_RG8;
-    case GPU_RG16UI:
-      return GL_RG16UI;
+    case GPU_R16I:
+      return GL_R16I;
+    case GPU_R16F:
+      return GL_R16F;
     case GPU_R16:
       return GL_R16;
-    case GPU_R8:
-      return GL_R8;
-    case GPU_R8UI:
-      return GL_R8UI;
     /* Special formats texture & renderbuffer */
     case GPU_R11F_G11F_B10F:
       return GL_R11F_G11F_B10F;
-    case GPU_DEPTH24_STENCIL8:
-      return GL_DEPTH24_STENCIL8;
     case GPU_DEPTH32F_STENCIL8:
       return GL_DEPTH32F_STENCIL8;
+    case GPU_DEPTH24_STENCIL8:
+      return GL_DEPTH24_STENCIL8;
+    case GPU_SRGB8_A8:
+      return GL_SRGB8_ALPHA8;
     /* Texture only format */
-    /* ** Add Format here */
+    case GPU_RGB16F:
+      return GL_RGB16F;
     /* Special formats texture only */
     /* ** Add Format here */
     /* Depth Formats */
@@ -470,6 +507,99 @@ static GLenum gpu_get_gl_internalformat(eGPUTextureFormat format)
   }
 }
 
+static eGPUTextureFormat gl_internalformat_to_gpu_format(const GLenum glformat)
+{
+  /* You can add any of the available type to this list
+   * For available types see GPU_texture.h */
+  switch (glformat) {
+    /* Formats texture & renderbuffer */
+    case GL_RGBA8UI:
+      return GPU_RGBA8UI;
+    case GL_RGBA8I:
+      return GPU_RGBA8I;
+    case GL_RGBA8:
+      return GPU_RGBA8;
+    case GL_RGBA32UI:
+      return GPU_RGBA32UI;
+    case GL_RGBA32I:
+      return GPU_RGBA32I;
+    case GL_RGBA32F:
+      return GPU_RGBA32F;
+    case GL_RGBA16UI:
+      return GPU_RGBA16UI;
+    case GL_RGBA16I:
+      return GPU_RGBA16I;
+    case GL_RGBA16F:
+      return GPU_RGBA16F;
+    case GL_RGBA16:
+      return GPU_RGBA16;
+    case GL_RG8UI:
+      return GPU_RG8UI;
+    case GL_RG8I:
+      return GPU_RG8I;
+    case GL_RG8:
+      return GPU_RG8;
+    case GL_RG32UI:
+      return GPU_RG32UI;
+    case GL_RG32I:
+      return GPU_RG32I;
+    case GL_RG32F:
+      return GPU_RG32F;
+    case GL_RG16UI:
+      return GPU_RG16UI;
+    case GL_RG16I:
+      return GPU_RG16I;
+    case GL_RG16F:
+      return GPU_RGBA32F;
+    case GL_RG16:
+      return GPU_RG16;
+    case GL_R8UI:
+      return GPU_R8UI;
+    case GL_R8I:
+      GPU_R8I;
+    case GL_R8:
+      return GPU_R8;
+    case GL_R32UI:
+      return GPU_R32UI;
+    case GL_R32I:
+      return GPU_R32I;
+    case GL_R32F:
+      return GPU_R32F;
+    case GL_R16UI:
+      return GPU_R16UI;
+    case GL_R16I:
+      return GPU_R16I;
+    case GL_R16F:
+      return GPU_R16F;
+    case GL_R16:
+      return GPU_R16;
+    /* Special formats texture & renderbuffer */
+    case GL_R11F_G11F_B10F:
+      return GPU_R11F_G11F_B10F;
+    case GL_DEPTH32F_STENCIL8:
+      return GPU_DEPTH32F_STENCIL8;
+    case GL_DEPTH24_STENCIL8:
+      return GPU_DEPTH24_STENCIL8;
+    case GL_SRGB8_ALPHA8:
+      return GPU_SRGB8_A8;
+    /* Texture only format */
+    case GL_RGB16F:
+      return GPU_RGB16F;
+    /* Special formats texture only */
+    /* ** Add Format here */
+    /* Depth Formats */
+    case GL_DEPTH_COMPONENT32F:
+      return GPU_DEPTH_COMPONENT32F;
+    case GL_DEPTH_COMPONENT24:
+      return GPU_DEPTH_COMPONENT24;
+    case GL_DEPTH_COMPONENT16:
+      return GPU_DEPTH_COMPONENT16;
+    default:
+      BLI_assert(!"Internal format incorrect or unsupported\n");
+      return -1;
+  }
+}
+
 static GLenum gpu_get_gl_datatype(eGPUDataFormat format)
 {
   switch (format) {
@@ -690,7 +820,7 @@ GPUTexture *GPU_texture_create_nD(int w,
   tex->refcount = 1;
   tex->format = tex_format;
   tex->components = gpu_get_component_count(tex_format);
-  tex->bytesize = gpu_get_bytesize(tex_format);
+  tex->mipmaps = 0;
   tex->format_flag = 0;
 
   if (n == 2) {
@@ -726,7 +856,7 @@ GPUTexture *GPU_texture_create_nD(int w,
     tex->target = GL_TEXTURE_2D_MULTISAMPLE;
   }
 
-  GLenum internalformat = gpu_get_gl_internalformat(tex_format);
+  GLenum internalformat = gpu_format_to_gl_internalformat(tex_format);
   GLenum data_format = gpu_get_gl_dataformat(tex_format, &tex->format_flag);
   GLenum data_type = gpu_get_gl_datatype(gpu_data_format);
 
@@ -877,7 +1007,7 @@ GPUTexture *GPU_texture_cube_create(int w,
   tex->refcount = 1;
   tex->format = tex_format;
   tex->components = gpu_get_component_count(tex_format);
-  tex->bytesize = gpu_get_bytesize(tex_format);
+  tex->mipmaps = 0;
   tex->format_flag = GPU_FORMAT_CUBE;
 
   if (d == 0) {
@@ -901,7 +1031,7 @@ GPUTexture *GPU_texture_cube_create(int w,
     }
   }
 
-  GLenum internalformat = gpu_get_gl_internalformat(tex_format);
+  GLenum internalformat = gpu_format_to_gl_internalformat(tex_format);
   GLenum data_format = gpu_get_gl_dataformat(tex_format, &tex->format_flag);
   GLenum data_type = gpu_get_gl_datatype(gpu_data_format);
 
@@ -1008,9 +1138,9 @@ GPUTexture *GPU_texture_create_buffer(eGPUTextureFormat tex_format, const GLuint
   tex->components = gpu_get_component_count(tex_format);
   tex->format_flag = 0;
   tex->target_base = tex->target = GL_TEXTURE_BUFFER;
-  tex->bytesize = gpu_get_bytesize(tex_format);
+  tex->mipmaps = 0;
 
-  GLenum internalformat = gpu_get_gl_internalformat(tex_format);
+  GLenum internalformat = gpu_format_to_gl_internalformat(tex_format);
 
   gpu_get_gl_dataformat(tex_format, &tex->format_flag);
 
@@ -1043,8 +1173,11 @@ GPUTexture *GPU_texture_create_buffer(eGPUTextureFormat tex_format, const GLuint
 
   glBindTexture(tex->target, tex->bindcode);
   glTexBuffer(tex->target, internalformat, buffer);
+  glGetTexLevelParameteriv(tex->ta

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list