diff options
Diffstat (limited to 'source/blender/gpu/intern/gpu_viewport.c')
-rw-r--r-- | source/blender/gpu/intern/gpu_viewport.c | 210 |
1 files changed, 141 insertions, 69 deletions
diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c index 62ba06b7a0a..7c2cb8cd4bb 100644 --- a/source/blender/gpu/intern/gpu_viewport.c +++ b/source/blender/gpu/intern/gpu_viewport.c @@ -33,11 +33,14 @@ #include <string.h> +#include "BLI_listbase.h" #include "BLI_rect.h" #include "BLI_string.h" #include "DNA_vec_types.h" +#include "BKE_global.h" + #include "GPU_framebuffer.h" #include "GPU_glew.h" #include "GPU_immediate.h" @@ -55,98 +58,172 @@ struct GPUViewport { GPUTexture *debug_depth; int size[2]; - /* Viewport Buffer Storage */ - /* TODO indentify to what engine conf are theses buffers */ - DefaultFramebufferList *fbl; - DefaultTextureList *txl; - DefaultPassList *psl; - StorageList *stl; + ListBase data; /* ViewportEngineData wrapped in LinkData */ + unsigned int data_hash; /* If hash mismatch we free all ViewportEngineData in this viewport */ - char engine_name[32]; + FramebufferList *fbl; + TextureList *txl; }; -static void GPU_viewport_buffers_free(GPUViewport *viewport); -static void GPU_viewport_passes_free(GPUViewport *viewport); -static void GPU_viewport_storage_free(GPUViewport *viewport); +static void GPU_viewport_buffers_free(FramebufferList *fbl, TextureList *txl); +static void GPU_viewport_storage_free(StorageList *stl); +static void GPU_viewport_passes_free(PassList *psl); GPUViewport *GPU_viewport_create(void) { GPUViewport *viewport = MEM_callocN(sizeof(GPUViewport), "GPUViewport"); viewport->fbl = MEM_callocN(sizeof(FramebufferList), "FramebufferList"); viewport->txl = MEM_callocN(sizeof(TextureList), "TextureList"); - viewport->psl = MEM_callocN(sizeof(PassList), "PassList"); - viewport->stl = MEM_callocN(sizeof(StorageList), "StorageList"); viewport->size[0] = viewport->size[1] = -1; return viewport; } -void GPU_viewport_get_engine_data(GPUViewport *viewport, void **fbs, void **txs, void **pss, void **str) +void *GPU_viewport_engine_data_create(GPUViewport *viewport, void *engine_type) { - *fbs = viewport->fbl; - *txs = viewport->txl; - *pss = viewport->psl; - *str = viewport->stl; + LinkData *ld = MEM_callocN(sizeof(LinkData), "LinkData"); + ViewportEngineData *data = MEM_callocN(sizeof(ViewportEngineData), "ViewportEngineData"); + data->engine_type = engine_type; + + data->fbl = MEM_callocN(sizeof(FramebufferList), "FramebufferList"); + data->txl = MEM_callocN(sizeof(TextureList), "TextureList"); + data->psl = MEM_callocN(sizeof(PassList), "PassList"); + data->stl = MEM_callocN(sizeof(StorageList), "StorageList"); + + ld->data = data; + BLI_addtail(&viewport->data, ld); + + return data; } -void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect, const char *engine) +static void GPU_viewport_engines_data_free(GPUViewport *viewport) { - /* add one pixel because of scissor test */ - int rect_w = BLI_rcti_size_x(rect) + 1, rect_h = BLI_rcti_size_y(rect) + 1; + LinkData *next; + for (LinkData *link = viewport->data.first; link; link = next) { + next = link->next; + ViewportEngineData *data = link->data; -#ifndef WITH_VIEWPORT_CACHE_TEST - /* TODO for testing only, we need proper cache invalidation */ - GPU_viewport_passes_free(viewport); -#endif + GPU_viewport_buffers_free(data->fbl, data->txl); + GPU_viewport_passes_free(data->psl); + GPU_viewport_storage_free(data->stl); + + MEM_freeN(data->fbl); + MEM_freeN(data->txl); + MEM_freeN(data->psl); + MEM_freeN(data->stl); + + MEM_freeN(data); + + BLI_remlink(&viewport->data, link); + MEM_freeN(link); + } +} + +void *GPU_viewport_engine_data_get(GPUViewport *viewport, void *engine_type) +{ + for (LinkData *link = viewport->data.first; link; link = link->next) { + ViewportEngineData *vdata = link->data; + if (vdata->engine_type == engine_type) { + return vdata; + } + } + return NULL; +} + +void *GPU_viewport_framebuffer_list_get(GPUViewport *viewport) +{ + return viewport->fbl; +} - if (!STREQ(engine, viewport->engine_name)) { - GPU_viewport_storage_free(viewport); - GPU_viewport_buffers_free(viewport); +void *GPU_viewport_texture_list_get(GPUViewport *viewport) +{ + return viewport->txl; +} + +void GPU_viewport_size_get(GPUViewport *viewport, int *size) +{ + size[0] = viewport->size[0]; + size[1] = viewport->size[1]; +} + +bool GPU_viewport_cache_validate(GPUViewport *viewport, unsigned int hash) +{ + bool dirty = false; + + /* TODO for testing only, we need proper cache invalidation */ + if (G.debug_value != 666 && G.debug_value != 667) { + for (LinkData *link = viewport->data.first; link; link = link->next) { + ViewportEngineData *data = link->data; + GPU_viewport_passes_free(data->psl); + } + dirty = true; + } - BLI_strncpy(viewport->engine_name, engine, 32); + if (viewport->data_hash != hash) { + GPU_viewport_engines_data_free(viewport); + dirty = true; } - if (viewport->fbl->default_fb) { + viewport->data_hash = hash; + + return dirty; +} + +void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect) +{ + DefaultFramebufferList *dfbl = (DefaultFramebufferList *)viewport->fbl; + DefaultTextureList *dtxl = (DefaultTextureList *)viewport->txl; + + /* add one pixel because of scissor test */ + int rect_w = BLI_rcti_size_x(rect) + 1; + int rect_h = BLI_rcti_size_y(rect) + 1; + + if (dfbl->default_fb) { if (rect_w != viewport->size[0] || rect_h != viewport->size[1]) { - GPU_viewport_buffers_free(viewport); + GPU_viewport_buffers_free(viewport->fbl, viewport->txl); + + for (LinkData *link = viewport->data.first; link; link = link->next) { + ViewportEngineData *data = link->data; + GPU_viewport_buffers_free(data->fbl, data->txl); + } } } - if (!viewport->fbl->default_fb) { + if (!dfbl->default_fb) { bool ok = true; viewport->size[0] = rect_w; viewport->size[1] = rect_h; - viewport->fbl->default_fb = GPU_framebuffer_create(); - if (!viewport->fbl->default_fb) { + dfbl->default_fb = GPU_framebuffer_create(); + if (!dfbl->default_fb) { ok = false; goto cleanup; } /* Color */ /* No multi samples for now */ - viewport->txl->color = GPU_texture_create_2D(rect_w, rect_h, NULL, NULL); - if (!viewport->txl->color) { + dtxl->color = GPU_texture_create_2D(rect_w, rect_h, NULL, NULL); + if (!dtxl->color) { ok = false; goto cleanup; } - if (!GPU_framebuffer_texture_attach(viewport->fbl->default_fb, viewport->txl->color, 0)) { + if (!GPU_framebuffer_texture_attach(dfbl->default_fb, dtxl->color, 0)) { ok = false; goto cleanup; } /* Depth */ - viewport->txl->depth = GPU_texture_create_depth(rect_w, rect_h, NULL); - if (!viewport->txl->depth) { + dtxl->depth = GPU_texture_create_depth(rect_w, rect_h, NULL); + if (!dtxl->depth) { ok = false; goto cleanup; } - else if (!GPU_framebuffer_texture_attach(viewport->fbl->default_fb, viewport->txl->depth, 0)) { + else if (!GPU_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0)) { ok = false; goto cleanup; } - else if (!GPU_framebuffer_check_valid(viewport->fbl->default_fb, NULL)) { + else if (!GPU_framebuffer_check_valid(dfbl->default_fb, NULL)) { ok = false; goto cleanup; } @@ -161,12 +238,14 @@ cleanup: GPU_framebuffer_restore(); } - GPU_framebuffer_slots_bind(viewport->fbl->default_fb, 0); + GPU_framebuffer_slots_bind(dfbl->default_fb, 0); } static void draw_ofs_to_screen(GPUViewport *viewport) { - GPUTexture *color = viewport->txl->color; + DefaultTextureList *dtxl = (DefaultTextureList *)viewport->txl; + + GPUTexture *color = dtxl->color; const float w = (float)GPU_texture_width(color); const float h = (float)GPU_texture_height(color); @@ -176,12 +255,11 @@ static void draw_ofs_to_screen(GPUViewport *viewport) unsigned pos = add_attrib(format, "pos", GL_FLOAT, 2, KEEP_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_MODULATE_ALPHA); - GPU_texture_bind(color, 0); immUniform1i("image", 0); /* default GL_TEXTURE0 unit */ - immBegin(GL_QUADS, 4); + immBegin(GL_TRIANGLE_STRIP, 4); immAttrib2f(texcoord, 0.0f, 0.0f); immVertex2f(pos, 0.0f, 0.0f); @@ -189,12 +267,12 @@ static void draw_ofs_to_screen(GPUViewport *viewport) immAttrib2f(texcoord, 1.0f, 0.0f); immVertex2f(pos, w, 0.0f); - immAttrib2f(texcoord, 1.0f, 1.0f); - immVertex2f(pos, w, h); - immAttrib2f(texcoord, 0.0f, 1.0f); immVertex2f(pos, 0.0f, h); + immAttrib2f(texcoord, 1.0f, 1.0f); + immVertex2f(pos, w, h); + immEnd(); GPU_texture_unbind(color); @@ -204,21 +282,22 @@ static void draw_ofs_to_screen(GPUViewport *viewport) void GPU_viewport_unbind(GPUViewport *viewport) { - if (viewport->fbl->default_fb) { + DefaultFramebufferList *dfbl = (DefaultFramebufferList *)viewport->fbl; + + if (dfbl->default_fb) { GPU_framebuffer_texture_unbind(NULL, NULL); GPU_framebuffer_restore(); glEnable(GL_SCISSOR_TEST); + glDisable(GL_DEPTH_TEST); /* This might be bandwidth limiting */ draw_ofs_to_screen(viewport); } } -static void GPU_viewport_buffers_free(GPUViewport *viewport) +static void GPU_viewport_buffers_free(FramebufferList *fbl, TextureList *txl) { - FramebufferList *fbl = (FramebufferList *)viewport->fbl; - TextureList *txl = (TextureList *)viewport->txl; int i; for (i = MAX_BUFFERS - 1; i > -1; --i) { GPUFrameBuffer *fb = fbl->framebuffers[i]; @@ -236,10 +315,8 @@ static void GPU_viewport_buffers_free(GPUViewport *viewport) } } -static void GPU_viewport_storage_free(GPUViewport *viewport) +static void GPU_viewport_storage_free(StorageList *stl) { - StorageList *stl = (StorageList *)viewport->stl; - for (int i = MAX_STORAGE - 1; i > -1; --i) { void *storage = stl->storage[i]; if (storage) { @@ -249,12 +326,9 @@ static void GPU_viewport_storage_free(GPUViewport *viewport) } } -static void GPU_viewport_passes_free(GPUViewport *viewport) +static void GPU_viewport_passes_free(PassList *psl) { - PassList *psl = (PassList *)viewport->psl; - int i; - - for (i = MAX_PASSES - 1; i > -1; --i) { + for (int i = MAX_PASSES - 1; i > -1; --i) { struct DRWPass *pass = psl->passes[i]; if (pass) { DRW_pass_free(pass); @@ -266,15 +340,13 @@ static void GPU_viewport_passes_free(GPUViewport *viewport) void GPU_viewport_free(GPUViewport *viewport) { - GPU_viewport_debug_depth_free(viewport); - GPU_viewport_buffers_free(viewport); - GPU_viewport_passes_free(viewport); - GPU_viewport_storage_free(viewport); + GPU_viewport_engines_data_free(viewport); + GPU_viewport_buffers_free(viewport->fbl, viewport->txl); MEM_freeN(viewport->fbl); MEM_freeN(viewport->txl); - MEM_freeN(viewport->psl); - MEM_freeN(viewport->stl); + + GPU_viewport_debug_depth_free(viewport); } /****************** debug ********************/ @@ -320,7 +392,7 @@ void GPU_viewport_debug_depth_draw(GPUViewport *viewport, const float znear, con immUniform1f("zfar", zfar); immUniform1i("image", 0); /* default GL_TEXTURE0 unit */ - immBegin(GL_QUADS, 4); + immBegin(GL_TRIANGLE_STRIP, 4); immAttrib2f(texcoord, 0.0f, 0.0f); immVertex2f(pos, 0.0f, 0.0f); @@ -328,12 +400,12 @@ void GPU_viewport_debug_depth_draw(GPUViewport *viewport, const float znear, con immAttrib2f(texcoord, 1.0f, 0.0f); immVertex2f(pos, w, 0.0f); - immAttrib2f(texcoord, 1.0f, 1.0f); - immVertex2f(pos, w, h); - immAttrib2f(texcoord, 0.0f, 1.0f); immVertex2f(pos, 0.0f, h); + immAttrib2f(texcoord, 1.0f, 1.0f); + immVertex2f(pos, w, h); + immEnd(); GPU_texture_unbind(viewport->debug_depth); |