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:
Diffstat (limited to 'source/blender/gpu/intern/gpu_viewport.c')
-rw-r--r--source/blender/gpu/intern/gpu_viewport.c210
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);