Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2017-05-16 03:59:25 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-05-16 21:27:52 +0300
commit7a029f4e00cc9a9f6a938cf701e6ed4c91115264 (patch)
treea315770fc2fbd5807ba262e9cbdcc179877d4125 /source/blender/gpu/intern/gpu_viewport.c
parentdc01586b4063142a3736993eb4a6e4fec893bed1 (diff)
GPUViewport: Add a Texture Pool to reuse textures across engines.
Diffstat (limited to 'source/blender/gpu/intern/gpu_viewport.c')
-rw-r--r--source/blender/gpu/intern/gpu_viewport.c67
1 files changed, 67 insertions, 0 deletions
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);