From 7a029f4e00cc9a9f6a938cf701e6ed4c91115264 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 16 May 2017 02:59:25 +0200 Subject: GPUViewport: Add a Texture Pool to reuse textures across engines. --- source/blender/gpu/intern/gpu_viewport.c | 67 ++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) (limited to 'source/blender/gpu/intern/gpu_viewport.c') 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); -- cgit v1.2.3