GPUViewport: Add a Texture Pool to reuse textures across engines.
This commit is contained in:
parent
dc01586b40
commit
7a029f4e00
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue