Commit: 7a029f4e00cc9a9f6a938cf701e6ed4c91115264
Author: Clément Foucault
Date:   Tue May 16 02:59:25 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB7a029f4e00cc9a9f6a938cf701e6ed4c91115264

GPUViewport: Add a Texture Pool to reuse textures across engines.

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

M       source/blender/gpu/GPU_texture.h
M       source/blender/gpu/GPU_viewport.h
M       source/blender/gpu/intern/gpu_texture.c
M       source/blender/gpu/intern/gpu_viewport.c

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

diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index 8cf9806ae36..b58cffd7214 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -191,6 +191,7 @@ void GPU_texture_framebuffer_set(GPUTexture *tex, struct 
GPUFrameBuffer *fb, int
 int GPU_texture_target(const GPUTexture *tex);
 int GPU_texture_width(const GPUTexture *tex);
 int GPU_texture_height(const GPUTexture *tex);
+int GPU_texture_format(const GPUTexture *tex);
 bool GPU_texture_depth(const GPUTexture *tex);
 bool GPU_texture_stencil(const GPUTexture *tex);
 int GPU_texture_opengl_bindcode(const GPUTexture *tex);
diff --git a/source/blender/gpu/GPU_viewport.h 
b/source/blender/gpu/GPU_viewport.h
index e5acc024ff4..2b2a07f50b7 100644
--- a/source/blender/gpu/GPU_viewport.h
+++ b/source/blender/gpu/GPU_viewport.h
@@ -101,6 +101,9 @@ void *GPU_viewport_texture_list_get(GPUViewport *viewport);
 void  GPU_viewport_size_get(const GPUViewport *viewport, int size[2]);
 void  GPU_viewport_size_set(GPUViewport *viewport, const int size[2]);
 
+/* Texture pool */
+GPUTexture *GPU_viewport_texture_pool_query(GPUViewport *viewport, void 
*engine, int width, int height, int channels, int format);
+
 bool GPU_viewport_cache_validate(GPUViewport *viewport, unsigned int hash);
 
 /* debug */
diff --git a/source/blender/gpu/intern/gpu_texture.c 
b/source/blender/gpu/intern/gpu_texture.c
index 637cdff1262..4be425b7eb9 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.c
@@ -65,6 +65,7 @@ struct GPUTexture {
        bool stencil;       /* is a stencil texture? */
 
        unsigned int bytesize; /* number of byte for one pixel */
+       int format;         /* GPUTextureFormat */
 };
 
 /* ------ Memory Management ------- */
@@ -318,6 +319,7 @@ static GPUTexture *GPU_texture_create_nD(
        tex->number = -1;
        tex->refcount = 1;
        tex->fb_attachment = -1;
+       tex->format = data_type;
 
        if (n == 2) {
                if (d == 0)
@@ -462,6 +464,7 @@ static GPUTexture *GPU_texture_cube_create(
        tex->number = -1;
        tex->refcount = 1;
        tex->fb_attachment = -1;
+       tex->format = data_type;
 
        if (d == 0) {
                tex->target_base = tex->target = GL_TEXTURE_CUBE_MAP;
@@ -551,6 +554,7 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser 
*iuser, int textarget
        tex->target = textarget;
        tex->target_base = textarget;
        tex->fromblender = 1;
+       tex->format = -1;
 
        ima->gputexture[gputt] = tex;
 
@@ -611,6 +615,7 @@ GPUTexture *GPU_texture_from_preview(PreviewImage *prv, int 
mipmap)
        tex->refcount = 1;
        tex->target = GL_TEXTURE_2D;
        tex->target_base = GL_TEXTURE_2D;
+       tex->format = -1;
        
        prv->gputexture[0] = tex;
        
@@ -944,6 +949,11 @@ int GPU_texture_height(const GPUTexture *tex)
        return tex->h;
 }
 
+int GPU_texture_format(const GPUTexture *tex)
+{
+       return tex->format;
+}
+
 bool GPU_texture_depth(const GPUTexture *tex)
 {
        return tex->depth;
diff --git a/source/blender/gpu/intern/gpu_viewport.c 
b/source/blender/gpu/intern/gpu_viewport.c
index c87b5099f0e..a965d4ef135 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -54,6 +54,17 @@
 static const int default_fbl_len = (sizeof(DefaultFramebufferList)) / 
sizeof(void *);
 static const int default_txl_len = (sizeof(DefaultTextureList)) / sizeof(void 
*);
 
+/* Maximum number of simultaneous engine enabled at the same time.
+ * Setting it lower than the real number will do lead to
+ * higher VRAM usage due to sub-efficient buffer reuse. */
+#define MAX_ENGINE_BUFFER_SHARING 5
+
+typedef struct ViewportTempTexture {
+       struct ViewportTempTexture *next, *prev;
+       void *user[MAX_ENGINE_BUFFER_SHARING];
+       GPUTexture *texture;
+} ViewportTempTexture;
+
 struct GPUViewport {
        float pad[4];
 
@@ -66,11 +77,14 @@ struct GPUViewport {
 
        DefaultFramebufferList *fbl;
        DefaultTextureList *txl;
+
+       ListBase tex_pool;  /* ViewportTempTexture list : Temporary textures 
shared across draw engines */
 };
 
 static void gpu_viewport_buffers_free(FramebufferList *fbl, int fbl_len, 
TextureList *txl, int txl_len);
 static void gpu_viewport_storage_free(StorageList *stl, int stl_len);
 static void gpu_viewport_passes_free(PassList *psl, int psl_len);
+static void gpu_viewport_texture_pool_free(GPUViewport *viewport);
 
 GPUViewport *GPU_viewport_create(void)
 {
@@ -153,6 +167,8 @@ static void gpu_viewport_engines_data_free(GPUViewport 
*viewport)
                BLI_remlink(&viewport->data, link);
                MEM_freeN(link);
        }
+
+       gpu_viewport_texture_pool_free(viewport);
 }
 
 void *GPU_viewport_engine_data_get(GPUViewport *viewport, void *engine_type)
@@ -192,6 +208,53 @@ void GPU_viewport_size_set(GPUViewport *viewport, const 
int size[2])
        viewport->size[1] = size[1];
 }
 
+/**
+ * Try to find a texture coresponding to params into the texture pool.
+ * If no texture was found, create one and add it to the pool.
+ */
+GPUTexture *GPU_viewport_texture_pool_query(GPUViewport *viewport, void 
*engine, int width, int height, int channels, int format)
+{
+       GPUTexture *tex;
+
+       for (ViewportTempTexture *tmp_tex = viewport->tex_pool.first; tmp_tex; 
tmp_tex = tmp_tex->next) {
+               if ((GPU_texture_width(tmp_tex->texture) == width) &&
+                       (GPU_texture_height(tmp_tex->texture) == height) &&
+                       (GPU_texture_format(tmp_tex->texture) == format))
+               {
+                       /* Search if the engine is not already using this 
texture */
+                       for (int i = 0; i < MAX_ENGINE_BUFFER_SHARING; ++i) {
+                               if (tmp_tex->user[i] == engine) {
+                                       break;
+                               }
+
+                               if (tmp_tex->user[i] == NULL) {
+                                       tmp_tex->user[i] = engine;
+                                       return tmp_tex->texture;
+                               }
+                       }
+               }
+       }
+
+       tex = GPU_texture_create_2D_custom(width, height, channels, format, 
NULL, NULL);
+
+       ViewportTempTexture *tmp_tex = MEM_callocN(sizeof(ViewportTempTexture), 
"ViewportTempTexture");
+       tmp_tex->texture = tex;
+       tmp_tex->user[0] = engine;
+
+       BLI_addtail(&viewport->tex_pool, tmp_tex);
+
+       return tex;
+}
+
+static void gpu_viewport_texture_pool_free(GPUViewport *viewport)
+{
+       for (ViewportTempTexture *tmp_tex = viewport->tex_pool.first; tmp_tex; 
tmp_tex = tmp_tex->next) {
+               GPU_texture_free(tmp_tex->texture);
+       }
+
+       BLI_freelistN(&viewport->tex_pool);
+}
+
 bool GPU_viewport_cache_validate(GPUViewport *viewport, unsigned int hash)
 {
        bool dirty = false;
@@ -238,6 +301,8 @@ void GPU_viewport_bind(GPUViewport *viewport, const rcti 
*rect)
                                
DRW_engine_viewport_data_size_get(data->engine_type, &fbl_len, &txl_len, NULL, 
NULL);
                                gpu_viewport_buffers_free(data->fbl, fbl_len, 
data->txl, txl_len);
                        }
+
+                       gpu_viewport_texture_pool_free(viewport);
                }
        }
 
@@ -408,6 +473,8 @@ void GPU_viewport_free(GPUViewport *viewport)
                (FramebufferList *)viewport->fbl, default_fbl_len,
                (TextureList *)viewport->txl, default_txl_len);
 
+       gpu_viewport_texture_pool_free(viewport);
+
        MEM_freeN(viewport->fbl);
        MEM_freeN(viewport->txl);

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to