diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2017-11-06 18:47:23 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2017-11-06 19:43:14 +0300 |
commit | ed555750eb8294005f54425094cb692f29830631 (patch) | |
tree | e0b0149dd5959080ca39bd53b3baefe527413f99 /source/blender/gpu | |
parent | 5d70e847dd6f5182fa67c3b08260fbb5366009b5 (diff) |
DRW: Use pseudo persistent memory pool for the rendering data structure.
This gets rid of the bottleneck of allocation / free of thousands of elements every frame.
Cache time (Eevee) (test scene is default file with cube duplicated 3241 times)
pre-patch: 23ms
post-patch: 14ms
Diffstat (limited to 'source/blender/gpu')
-rw-r--r-- | source/blender/gpu/GPU_viewport.h | 16 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_viewport.c | 54 |
2 files changed, 56 insertions, 14 deletions
diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h index 622b3b301e4..f2bb05a6d1e 100644 --- a/source/blender/gpu/GPU_viewport.h +++ b/source/blender/gpu/GPU_viewport.h @@ -43,6 +43,17 @@ typedef struct GPUViewport GPUViewport; +/* Contains memory pools informations */ +typedef struct ViewportMemoryPool { + struct BLI_mempool *calls; + struct BLI_mempool *calls_generate; + struct BLI_mempool *calls_dynamic; + struct BLI_mempool *shgroups; + struct BLI_mempool *uniforms; + struct BLI_mempool *attribs; + struct BLI_mempool *passes; +} ViewportMemoryPool; + /* All FramebufferLists are just the same pointers with different names */ typedef struct FramebufferList { struct GPUFrameBuffer *framebuffers[0]; @@ -94,6 +105,8 @@ void GPU_viewport_free(GPUViewport *viewport); GPUViewport *GPU_viewport_create_from_offscreen(struct GPUOffScreen *ofs); void GPU_viewport_clear_from_offscreen(GPUViewport *viewport); +ViewportMemoryPool *GPU_viewport_mempool_get(GPUViewport *viewport); + void *GPU_viewport_engine_data_create(GPUViewport *viewport, void *engine_type); void *GPU_viewport_engine_data_get(GPUViewport *viewport, void *engine_type); void *GPU_viewport_framebuffer_list_get(GPUViewport *viewport); @@ -107,7 +120,8 @@ bool GPU_viewport_do_update(GPUViewport *viewport); /* 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); +bool GPU_viewport_engines_data_validate(GPUViewport *viewport, unsigned int hash); +void GPU_viewport_cache_release(GPUViewport *viewport); /* debug */ bool GPU_viewport_debug_depth_create(GPUViewport *viewport, int width, int height, char err_out[256]); diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c index 058f6ced40b..bdbf829a1ca 100644 --- a/source/blender/gpu/intern/gpu_viewport.c +++ b/source/blender/gpu/intern/gpu_viewport.c @@ -36,6 +36,7 @@ #include "BLI_listbase.h" #include "BLI_rect.h" #include "BLI_string.h" +#include "BLI_mempool.h" #include "DNA_vec_types.h" #include "DNA_userdef_types.h" @@ -82,6 +83,8 @@ struct GPUViewport { DefaultFramebufferList *fbl; DefaultTextureList *txl; + ViewportMemoryPool vmempool; /* Used for rendering data structure. */ + ListBase tex_pool; /* ViewportTempTexture list : Temporary textures shared across draw engines */ }; @@ -202,6 +205,11 @@ void *GPU_viewport_engine_data_get(GPUViewport *viewport, void *engine_type) return NULL; } +ViewportMemoryPool *GPU_viewport_mempool_get(GPUViewport *viewport) +{ + return &viewport->vmempool; +} + void *GPU_viewport_framebuffer_list_get(GPUViewport *viewport) { return viewport->fbl; @@ -296,21 +304,10 @@ static void gpu_viewport_texture_pool_free(GPUViewport *viewport) BLI_freelistN(&viewport->tex_pool); } -bool GPU_viewport_cache_validate(GPUViewport *viewport, unsigned int hash) +bool GPU_viewport_engines_data_validate(GPUViewport *viewport, unsigned int hash) { bool dirty = false; - /* TODO for testing only, we need proper cache invalidation */ - if (ELEM(G.debug_value, 666, 667) == false) { - for (LinkData *link = viewport->data.first; link; link = link->next) { - ViewportEngineData *data = link->data; - int psl_len; - DRW_engine_viewport_data_size_get(data->engine_type, NULL, NULL, &psl_len, NULL); - gpu_viewport_passes_free(data->psl, psl_len); - } - dirty = true; - } - if (viewport->data_hash != hash) { gpu_viewport_engines_data_free(viewport); dirty = true; @@ -321,6 +318,16 @@ bool GPU_viewport_cache_validate(GPUViewport *viewport, unsigned int hash) return dirty; } +void GPU_viewport_cache_release(GPUViewport *viewport) +{ + for (LinkData *link = viewport->data.first; link; link = link->next) { + ViewportEngineData *data = link->data; + int psl_len; + DRW_engine_viewport_data_size_get(data->engine_type, NULL, NULL, &psl_len, NULL); + gpu_viewport_passes_free(data->psl, psl_len); + } +} + void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect) { DefaultFramebufferList *dfbl = viewport->fbl; @@ -551,7 +558,6 @@ static void gpu_viewport_passes_free(PassList *psl, int psl_len) struct DRWPass *pass = psl->passes[i]; if (pass) { DRW_pass_free(pass); - MEM_freeN(pass); psl->passes[i] = NULL; } } @@ -570,6 +576,28 @@ void GPU_viewport_free(GPUViewport *viewport) MEM_freeN(viewport->fbl); MEM_freeN(viewport->txl); + if (viewport->vmempool.calls != NULL) { + BLI_mempool_destroy(viewport->vmempool.calls); + } + if (viewport->vmempool.calls_generate != NULL) { + BLI_mempool_destroy(viewport->vmempool.calls_generate); + } + if (viewport->vmempool.calls_dynamic != NULL) { + BLI_mempool_destroy(viewport->vmempool.calls_dynamic); + } + if (viewport->vmempool.shgroups != NULL) { + BLI_mempool_destroy(viewport->vmempool.shgroups); + } + if (viewport->vmempool.uniforms != NULL) { + BLI_mempool_destroy(viewport->vmempool.uniforms); + } + if (viewport->vmempool.attribs != NULL) { + BLI_mempool_destroy(viewport->vmempool.attribs); + } + if (viewport->vmempool.passes != NULL) { + BLI_mempool_destroy(viewport->vmempool.passes); + } + GPU_viewport_debug_depth_free(viewport); } |