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
path: root/source
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2017-02-08 23:44:13 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-02-09 13:25:51 +0300
commit6b372e3a22cbcdcb17a6239238189d6659418516 (patch)
treea756faafc16547d2d293e643634d22fa7a8075ac /source
parent09af91e0966afadd986a5a480e626698b2029826 (diff)
Clay Engine: support for overrides (not working yet)
Diffstat (limited to 'source')
-rw-r--r--source/blender/draw/engines/clay/clay.c269
-rw-r--r--source/blender/draw/engines/clay/shaders/clay_frag.glsl4
-rw-r--r--source/blender/draw/intern/DRW_render.h2
-rw-r--r--source/blender/draw/intern/draw_manager.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c2
-rw-r--r--source/blender/gpu/GPU_viewport.h9
-rw-r--r--source/blender/gpu/intern/gpu_viewport.c33
7 files changed, 199 insertions, 124 deletions
diff --git a/source/blender/draw/engines/clay/clay.c b/source/blender/draw/engines/clay/clay.c
index 3a844d328f2..5feac489607 100644
--- a/source/blender/draw/engines/clay/clay.c
+++ b/source/blender/draw/engines/clay/clay.c
@@ -58,8 +58,10 @@ typedef struct CLAY_UBO_Material {
float pad[2]; /* ensure 16 bytes alignement */
} CLAY_UBO_Material; /* 48 bytes */
+#define MAX_CLAY_MAT 512 /* 512 = 9 bit material id */
+
typedef struct CLAY_UBO_Storage {
- CLAY_UBO_Material materials[512]; /* 512 = 9 bit material id */
+ CLAY_UBO_Material materials[MAX_CLAY_MAT];
} CLAY_UBO_Storage;
static struct CLAY_data {
@@ -68,11 +70,6 @@ static struct CLAY_data {
/* Shading Pass */
struct GPUShader *clay_sh;
- /* Materials Parameter UBO */
- struct GPUUniformBuffer *mat_ubo;
- CLAY_UBO_Storage mat_storage;
- short ubo_flag;
-
/* Matcap textures */
struct GPUTexture *matcap_array;
float matcap_colors[24][3];
@@ -85,11 +82,23 @@ static struct CLAY_data {
struct GPUTexture *sampling_tx;
} data = {NULL};
-/* CLAY_data.ubo_flag */
-enum {
- CLAY_UBO_CLEAR = (1 << 0),
- CLAY_UBO_REFRESH = (1 << 1),
-};
+/* GPUViewport.storage
+ * Is freed everytime the viewport engine changes */
+typedef struct CLAY_Storage {
+ /* Materials Parameter UBO */
+ CLAY_UBO_Storage mat_storage;
+ int ubo_current_id;
+ DRWShadingGroup *shgrps[MAX_CLAY_MAT];
+} CLAY_Storage;
+
+/* Just a serie of int from 0 to MAX_CLAY_MAT-1 */
+static int ubo_mat_idxs[MAX_CLAY_MAT] = {0};
+
+/* keep it under MAX_STORAGE */
+typedef struct CLAY_StorageList {
+ struct CLAY_Storage *storage;
+ struct GPUUniformBuffer *mat_ubo;
+} CLAY_StorageList;
/* keep it under MAX_BUFFERS */
typedef struct CLAY_FramebufferList{
@@ -274,10 +283,8 @@ MaterialEngineSettings *CLAY_material_settings_create(void)
return (MaterialEngineSettings *)settings;
}
-static void CLAY_engine_init(const bContext *C)
+static void CLAY_engine_init(CLAY_StorageList *stl)
{
- Main *bmain = CTX_data_main(C);
-
/* Create Texture Array */
if (!data.matcap_array) {
PreviewImage *prv[24]; /* For now use all of the 24 internal matcaps */
@@ -327,10 +334,6 @@ static void CLAY_engine_init(const bContext *C)
data.depth_sh = DRW_shader_create_3D_depth_only();
}
- if (!data.mat_ubo) {
- data.mat_ubo = DRW_uniformbuffer_create(sizeof(CLAY_UBO_Storage), NULL);
- }
-
/* Shading pass */
if (!data.clay_sh) {
DynStr *ds = BLI_dynstr_new();
@@ -356,27 +359,20 @@ static void CLAY_engine_init(const bContext *C)
MEM_freeN(matcap_with_ao);
}
- /* Cleanup all runtime data loaded from file */
- for (Scene *sce = bmain->scene.first; sce; sce = sce->id.next) {
- /* Using render settings as material settings */
- MaterialEngineSettingsClay *res = DRW_render_settings_get(sce, RE_engine_id_BLENDER_CLAY);
- res->flag = CLAY_OUTDATED;
- res->ubo_index = -1;
-
- /* Update Collections Materials */
- for (SceneLayer *sl = sce->render_layers.first; sl; sl = sl->next) {
- for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
- CollectionEngineSettings *ces;
- ces = BKE_layer_collection_engine_get(lc, RE_engine_id_BLENDER_CLAY);
- if (ces) { /* May not exists */
- BKE_collection_engine_property_value_set_int(ces, "flag", CLAY_OUTDATED);
- BKE_collection_engine_property_value_set_int(ces, "ubo_index", -1);
- }
- }
- }
+ if (!stl->storage) {
+ stl->storage = MEM_callocN(sizeof(CLAY_Storage), "CLAY_Storage");
+ }
+
+ if (!stl->mat_ubo) {
+ stl->mat_ubo = DRW_uniformbuffer_create(sizeof(CLAY_UBO_Storage), NULL);
}
- data.ubo_flag |= CLAY_UBO_REFRESH;
+ if (ubo_mat_idxs[1] == 0) {
+ /* Just int to have pointers to them */
+ for (int i = 0; i < MAX_CLAY_MAT; ++i) {
+ ubo_mat_idxs[i] = i;
+ }
+ }
}
static void CLAY_ssao_setup(void)
@@ -430,7 +426,7 @@ static void CLAY_ssao_setup(void)
}
}
-static DRWShadingGroup *CLAY_shgroup_create(DRWPass *pass, int *UNUSED(material_id))
+static DRWShadingGroup *CLAY_shgroup_create(DRWPass *pass, int *material_id)
{
const int depthloc = 0, matcaploc = 1, jitterloc = 2, sampleloc = 3;
@@ -445,7 +441,7 @@ static DRWShadingGroup *CLAY_shgroup_create(DRWPass *pass, int *UNUSED(material_
DRW_shgroup_uniform_vec4(grp, "ssao_params", data.ssao_params, 1);
DRW_shgroup_uniform_vec3(grp, "matcaps_color", (float *)data.matcap_colors, 24);
- //DRW_shgroup_uniform_int(grp, "material_id", material_id, 1);
+ DRW_shgroup_uniform_int(grp, "mat_id", material_id, 1);
#ifndef GTAO
DRW_shgroup_uniform_texture(grp, "ssao_jitter", data.jitter_tx, jitterloc);
@@ -455,11 +451,39 @@ static DRWShadingGroup *CLAY_shgroup_create(DRWPass *pass, int *UNUSED(material_
return grp;
}
-static void update_ubo_storage(float matcap_rot, float matcap_hue, float matcap_sat, float matcap_val,
- float ssao_distance, float ssao_factor_cavity, float ssao_factor_edge,
- float ssao_attenuation, int matcap_icon, unsigned int current_id)
+static int search_mat_to_ubo(CLAY_Storage *storage, float matcap_rot, float matcap_hue, float matcap_sat,
+ float matcap_val, float ssao_distance, float ssao_factor_cavity,
+ float ssao_factor_edge, float ssao_attenuation, int matcap_icon)
{
- CLAY_UBO_Material *ubo = &data.mat_storage.materials[current_id];
+ /* For now just use a linear search and test all parameters */
+ /* TODO make a hash table */
+ for (int i = 0; i < storage->ubo_current_id; ++i)
+ {
+ CLAY_UBO_Material *ubo = &storage->mat_storage.materials[i];
+
+ if ((ubo->matcap_rot[0] == cosf(matcap_rot * 3.14159f * 2.0f)) &&
+ (ubo->matcap_hsv[0] == matcap_hue + 0.5f) &&
+ (ubo->matcap_hsv[1] == matcap_sat * 2.0f) &&
+ (ubo->matcap_hsv[2] == matcap_val * 2.0f) &&
+ (ubo->ssao_params_var[0] == ssao_distance) &&
+ (ubo->ssao_params_var[1] == ssao_factor_cavity) &&
+ (ubo->ssao_params_var[2] == ssao_factor_edge) &&
+ (ubo->ssao_params_var[3] == ssao_attenuation) &&
+ (ubo->matcap_id == matcap_to_index(matcap_icon)))
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+static int push_mat_to_ubo(CLAY_Storage *storage, float matcap_rot, float matcap_hue, float matcap_sat,
+ float matcap_val, float ssao_distance, float ssao_factor_cavity,
+ float ssao_factor_edge, float ssao_attenuation, int matcap_icon)
+{
+ int id = storage->ubo_current_id;
+ CLAY_UBO_Material *ubo = &storage->mat_storage.materials[id];
ubo->matcap_rot[0] = cosf(matcap_rot * 3.14159f * 2.0f);
ubo->matcap_rot[1] = sinf(matcap_rot * 3.14159f * 2.0f);
@@ -473,92 +497,115 @@ static void update_ubo_storage(float matcap_rot, float matcap_hue, float matcap_
ubo->ssao_params_var[2] = ssao_factor_edge;
ubo->ssao_params_var[3] = ssao_attenuation;
-
ubo->matcap_id = matcap_to_index(matcap_icon);
-}
-static void CLAY_update_material_ubo(const struct bContext *C)
-{
- Main *bmain = CTX_data_main(C);
+ storage->ubo_current_id++;
- /* Update Default materials */
- for (Scene *sce = bmain->scene.first; sce; sce = sce->id.next) {
- /* Using render settings as material settings */
- MaterialEngineSettingsClay *res = DRW_render_settings_get(sce, RE_engine_id_BLENDER_CLAY);
-
- if (res->flag & CLAY_OUTDATED)
- data.ubo_flag |= CLAY_UBO_REFRESH;
+ return id;
+}
- if (res->matcap_icon < ICON_MATCAP_01 ||
- res->matcap_icon > ICON_MATCAP_24)
- {
- res->matcap_icon = ICON_MATCAP_01;
- }
+static int mat_in_ubo(CLAY_Storage *storage, struct GPUUniformBuffer *ubo, DRWPass *pass,
+ float matcap_rot, float matcap_hue, float matcap_sat,
+ float matcap_val, float ssao_distance, float ssao_factor_cavity,
+ float ssao_factor_edge, float ssao_attenuation, int matcap_icon)
+{
+ int id;
- res->flag &= ~CLAY_OUTDATED;
+ /* Search material in UBO */
+ id = search_mat_to_ubo(storage, matcap_rot, matcap_hue, matcap_sat, matcap_val,
+ ssao_distance, ssao_factor_cavity, ssao_factor_edge,
+ ssao_attenuation, matcap_icon);
+ /* if not found create it */
+ if (id == -1) {
+ id = push_mat_to_ubo(storage, matcap_rot, matcap_hue, matcap_sat, matcap_val,
+ ssao_distance, ssao_factor_cavity, ssao_factor_edge,
+ ssao_attenuation, matcap_icon);
- /* Update Collections Materials */
- for (SceneLayer *sl = sce->render_layers.first; sl; sl = sl->next) {
- for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
- CollectionEngineSettings *ces;
- ces = BKE_layer_collection_engine_get(lc, RE_engine_id_BLENDER_CLAY);
+ storage->shgrps[id] = CLAY_shgroup_create(pass, &ubo_mat_idxs[id]);
- BKE_collection_engine_property_value_set_int(ces, "flag", 0);
- BKE_collection_engine_property_value_set_int(ces, "ubo_index", 0);
- }
+ /* if it's the first shgrp, pass bind the material UBO */
+ if (storage->ubo_current_id == 1) {
+ DRW_shgroup_uniform_block(storage->shgrps[0], "material_block", ubo, 0);
}
}
- if (data.ubo_flag & CLAY_UBO_REFRESH) {
- int current_id = 0;
+ return id;
+}
+/* Safe way to get override values */
+static void override_setting(CollectionEngineSettings *ces, const char *name, void *ret)
+{
+ CollectionEngineProperty *cep = BKE_collection_engine_property_get(ces, name);
- /* Default materials */
- for (Scene *sce = bmain->scene.first; sce; sce = sce->id.next) {
- MaterialEngineSettingsClay *res = DRW_render_settings_get(sce, RE_engine_id_BLENDER_CLAY);
+ if (!cep) return;
+ if ((cep->flag & COLLECTION_PROP_USE) == 0) return;
- update_ubo_storage(res->matcap_rot, res->matcap_hue, res->matcap_sat, res->matcap_val,
- res->ssao_distance, res->ssao_factor_cavity, res->ssao_factor_edge,
- res->ssao_attenuation, res->matcap_icon, current_id);
- current_id++;
+ if (cep->type == COLLECTION_PROP_TYPE_INT) {
+ CollectionEnginePropertyInt *prop = (CollectionEnginePropertyInt *)cep;
+ *((int *)ret) = prop->value;
+ }
+ else {
+ CollectionEnginePropertyInt *prop = (CollectionEnginePropertyInt *)cep;
+ *((float *)ret) = prop->value;
+ }
+}
- for (SceneLayer *sl = sce->render_layers.first; sl; sl = sl->next) {
- for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
- /* TODO */
- current_id++;
- }
- }
- current_id++;
- }
+static DRWShadingGroup *CLAY_object_shgrp_get(Object *ob, CLAY_StorageList *stl, DRWPass *pass)
+{
+ MaterialEngineSettingsClay *settings = DRW_render_settings_get(NULL, RE_engine_id_BLENDER_CLAY);
+ CollectionEngineSettings *ces = ob->collection_settings;
+
+ /* Default Settings */
+ float matcap_rot = settings->matcap_rot;
+ float matcap_hue = settings->matcap_hue;
+ float matcap_sat = settings->matcap_sat;
+ float matcap_val = settings->matcap_val;
+ float ssao_distance = settings->ssao_distance;
+ float ssao_factor_cavity = settings->ssao_factor_cavity;
+ float ssao_factor_edge = settings->ssao_factor_edge;
+ float ssao_attenuation = settings->ssao_attenuation;
+ int matcap_icon = settings->matcap_icon;
+
+ /* Override settings */
+ if (ces) {
+ override_setting(ces, "matcap_rotation", &matcap_rot);
+ override_setting(ces, "matcap_hue", &matcap_hue);
+ override_setting(ces, "matcap_saturation", &matcap_sat);
+ override_setting(ces, "matcap_value", &matcap_val);
+ override_setting(ces, "ssao_distance", &ssao_distance);
+ override_setting(ces, "ssao_factor_cavity", &ssao_factor_cavity);
+ override_setting(ces, "ssao_factor_edge", &ssao_factor_edge);
+ override_setting(ces, "ssao_attenuation", &ssao_attenuation);
+ override_setting(ces, "matcap_icon", &matcap_icon);
+ };
- DRW_uniformbuffer_update(data.mat_ubo, &data.mat_storage);
- }
+ int index = mat_in_ubo(stl->storage, stl->mat_ubo, pass,
+ matcap_rot, matcap_hue, matcap_sat, matcap_val,
+ ssao_distance, ssao_factor_cavity, ssao_factor_edge,
+ ssao_attenuation, matcap_icon);
- data.ubo_flag = 0;
+ return stl->storage->shgrps[index];
}
-static void CLAY_create_cache(CLAY_PassList *passes, const struct bContext *C)
+static void CLAY_create_cache(CLAY_PassList *passes, CLAY_StorageList *stl, const struct bContext *C)
{
SceneLayer *sl = CTX_data_scene_layer(C);
- DRWShadingGroup *default_shgrp, *depthbatch;
+ DRWShadingGroup *clay_shgrp;
+ DRWShadingGroup *depth_shgrp;
/* Depth Pass */
{
passes->depth_pass = DRW_pass_create("Depth Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
- depthbatch = DRW_shgroup_create(data.depth_sh, passes->depth_pass);
+ depth_shgrp = DRW_shgroup_create(data.depth_sh, passes->depth_pass);
}
/* Clay Pass */
{
- MaterialEngineSettingsClay *settings = DRW_render_settings_get(NULL, RE_engine_id_BLENDER_CLAY);
-
- passes->clay_pass = DRW_pass_create("Clay Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
-
- default_shgrp = CLAY_shgroup_create(passes->clay_pass, &settings->ubo_index);
- DRW_shgroup_uniform_block(default_shgrp, "material_block", data.mat_ubo, 0);
+ passes->clay_pass = DRW_pass_create("Clay Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS);
+ stl->storage->ubo_current_id = 0;
}
/* Object Mode */
@@ -582,11 +629,14 @@ static void CLAY_create_cache(CLAY_PassList *passes, const struct bContext *C)
switch (ob->type) {
case OB_MESH:
+ clay_shgrp = CLAY_object_shgrp_get(ob, stl, passes->clay_pass);
geom = DRW_cache_surface_get(ob);
/* Add everything for now */
- DRW_shgroup_call_add(depthbatch, geom, ob->obmat);
- DRW_shgroup_call_add(default_shgrp, geom, ob->obmat);
+ DRW_shgroup_call_add(depth_shgrp, geom, ob->obmat);
+
+ if (clay_shgrp)
+ DRW_shgroup_call_add(clay_shgrp, geom, ob->obmat);
//DRW_shgroup_wire_overlay(passes->wire_overlay_pass, ob);
@@ -614,6 +664,8 @@ static void CLAY_create_cache(CLAY_PassList *passes, const struct bContext *C)
DRW_shgroup_relationship_lines(passes->non_meshes_pass, ob);
}
DEG_OBJECT_ITER_END
+
+ DRW_uniformbuffer_update(stl->mat_ubo, &stl->storage->mat_storage);
}
static void CLAY_view_draw(RenderEngine *UNUSED(engine), const bContext *context)
@@ -623,12 +675,11 @@ static void CLAY_view_draw(RenderEngine *UNUSED(engine), const bContext *context
CLAY_FramebufferList *buffers = NULL;
CLAY_TextureList *textures = NULL;
CLAY_PassList *passes = NULL;
+ CLAY_StorageList *storage = NULL;
- DRW_viewport_init(context, (void **)&buffers, (void **)&textures, (void **)&passes);
-
- CLAY_engine_init(context);
+ DRW_viewport_init(context, (void **)&buffers, (void **)&textures, (void **)&passes, (void **)&storage);
- CLAY_update_material_ubo(context);
+ CLAY_engine_init(storage);
/* TODO : tag to refresh by the deps graph */
/* ideally only refresh when objects are added/removed */
@@ -644,7 +695,7 @@ static void CLAY_view_draw(RenderEngine *UNUSED(engine), const bContext *context
#ifdef WITH_VIEWPORT_CACHE_TEST
once = true;
#endif
- CLAY_create_cache(passes, context);
+ CLAY_create_cache(passes, storage, context);
}
/* Start Drawing */
@@ -685,10 +736,6 @@ static void CLAY_collection_settings_create(RenderEngine *UNUSED(engine), Collec
BKE_collection_engine_property_add_float(ces, "ssao_attenuation", 1.0f);
BKE_collection_engine_property_add_float(ces, "ssao_factor_cavity", 1.0f);
BKE_collection_engine_property_add_float(ces, "ssao_factor_edge", 1.0f);
-
- /* Runtime data (not display in settings) */
- BKE_collection_engine_property_add_int(ces, "ubo_index", -1);
- BKE_collection_engine_property_add_int(ces, "flag", CLAY_OUTDATED);
}
void clay_engine_free(void)
@@ -709,10 +756,6 @@ void clay_engine_free(void)
if (data.sampling_tx) {
DRW_texture_free(data.sampling_tx);
}
-
- if (data.mat_ubo) {
- DRW_uniformbuffer_free(data.mat_ubo);
- }
}
RenderEngineType viewport_clay_type = {
diff --git a/source/blender/draw/engines/clay/shaders/clay_frag.glsl b/source/blender/draw/engines/clay/shaders/clay_frag.glsl
index d9b372b652a..7a38db35bcf 100644
--- a/source/blender/draw/engines/clay/shaders/clay_frag.glsl
+++ b/source/blender/draw/engines/clay/shaders/clay_frag.glsl
@@ -27,7 +27,7 @@ layout(std140) uniform material_block {
Material matcaps_param[MAX_MATERIAL];
};
-int mat_id;
+uniform int mat_id;
/* Aliases */
#define ssao_samples_num ssao_params.x
@@ -170,8 +170,6 @@ void main() {
vec3 position = get_view_space_from_depth(screenco, depth);
vec3 normal = calculate_view_space_normal(position);
- //mat_id = int(screenco.x*3.0);
-
/* Manual Depth test */
/* Doing this test earlier gives problem with dfdx calculations
* TODO move this before when we have proper geometric normals */
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 90412e65a51..2cd06341682 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -194,7 +194,7 @@ typedef enum {
DRW_MAT_WIN,
} DRWViewportMatrixType;
-void DRW_viewport_init(const bContext *C, void **buffers, void **textures, void **passes);
+void DRW_viewport_init(const bContext *C, void **buffers, void **textures, void **passes, void **storage);
void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type);
float *DRW_viewport_size_get(void);
float *DRW_viewport_screenvecs_get(void);
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index a7ce65060e6..983f22bad52 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -1071,12 +1071,12 @@ float *DRW_viewport_pixelsize_get(void)
return &DST.pixsize;
}
-void DRW_viewport_init(const bContext *C, void **buffers, void **textures, void **passes)
+void DRW_viewport_init(const bContext *C, void **buffers, void **textures, void **passes, void **storage)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
GPUViewport *viewport = rv3d->viewport;
- GPU_viewport_get_engine_data(viewport, buffers, textures, passes);
+ GPU_viewport_get_engine_data(viewport, buffers, textures, passes, storage);
/* Refresh DST.size */
DefaultTextureList *txl = (DefaultTextureList *)*textures;
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 1ac4f1529e3..0427498bf41 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -2141,7 +2141,7 @@ void view3d_main_region_draw(const bContext *C, ARegion *ar)
if (!rv3d->viewport)
rv3d->viewport = GPU_viewport_create();
- GPU_viewport_bind(rv3d->viewport, &ar->winrct);
+ GPU_viewport_bind(rv3d->viewport, &ar->winrct, scene->r.engine);
/* TODO viewport - there is so much to be done, in fact a lot will need to happen in the space_view3d.c
* before we even call the drawing routine, but let's move on for now (dfelinto)
diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h
index e44657a4647..9de16f64ca1 100644
--- a/source/blender/gpu/GPU_viewport.h
+++ b/source/blender/gpu/GPU_viewport.h
@@ -44,6 +44,7 @@ typedef struct GPUViewport GPUViewport;
#define MAX_BUFFERS 8
#define MAX_TEXTURES 16
#define MAX_PASSES 16
+#define MAX_STORAGE 2 /* extend if needed */
/* All FramebufferLists are just the same pointers with different names */
typedef struct FramebufferList {
@@ -58,6 +59,10 @@ typedef struct PassList {
struct DRWPass *passes[MAX_TEXTURES];
} PassList;
+typedef struct StorageList {
+ void *storage[MAX_STORAGE]; /* custom structs from the engine */
+} StorageList;
+
/* Buffer and textures used by the viewport by default */
typedef struct DefaultFramebufferList {
struct GPUFrameBuffer *default_fb;
@@ -74,11 +79,11 @@ typedef struct DefaultPassList {
} DefaultPassList;
GPUViewport *GPU_viewport_create(void);
-void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect);
+void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect, const char *engine);
void GPU_viewport_unbind(GPUViewport *viewport);
void GPU_viewport_free(GPUViewport *viewport);
-void GPU_viewport_get_engine_data(GPUViewport *viewport, void **fbs, void **txs, void **pss);
+void GPU_viewport_get_engine_data(GPUViewport *viewport, void **fbs, void **txs, void **pss, void **str);
/* 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 b1964857ab1..62ba06b7a0a 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -34,6 +34,7 @@
#include <string.h>
#include "BLI_rect.h"
+#include "BLI_string.h"
#include "DNA_vec_types.h"
@@ -59,10 +60,14 @@ struct GPUViewport {
DefaultFramebufferList *fbl;
DefaultTextureList *txl;
DefaultPassList *psl;
+ StorageList *stl;
+
+ char engine_name[32];
};
static void GPU_viewport_buffers_free(GPUViewport *viewport);
static void GPU_viewport_passes_free(GPUViewport *viewport);
+static void GPU_viewport_storage_free(GPUViewport *viewport);
GPUViewport *GPU_viewport_create(void)
{
@@ -70,19 +75,21 @@ GPUViewport *GPU_viewport_create(void)
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 GPU_viewport_get_engine_data(GPUViewport *viewport, void **fbs, void **txs, void **pss, void **str)
{
*fbs = viewport->fbl;
*txs = viewport->txl;
*pss = viewport->psl;
+ *str = viewport->stl;
}
-void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect)
+void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect, const char *engine)
{
/* add one pixel because of scissor test */
int rect_w = BLI_rcti_size_x(rect) + 1, rect_h = BLI_rcti_size_y(rect) + 1;
@@ -92,6 +99,13 @@ void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect)
GPU_viewport_passes_free(viewport);
#endif
+ if (!STREQ(engine, viewport->engine_name)) {
+ GPU_viewport_storage_free(viewport);
+ GPU_viewport_buffers_free(viewport);
+
+ BLI_strncpy(viewport->engine_name, engine, 32);
+ }
+
if (viewport->fbl->default_fb) {
if (rect_w != viewport->size[0] || rect_h != viewport->size[1]) {
GPU_viewport_buffers_free(viewport);
@@ -222,6 +236,19 @@ static void GPU_viewport_buffers_free(GPUViewport *viewport)
}
}
+static void GPU_viewport_storage_free(GPUViewport *viewport)
+{
+ StorageList *stl = (StorageList *)viewport->stl;
+
+ for (int i = MAX_STORAGE - 1; i > -1; --i) {
+ void *storage = stl->storage[i];
+ if (storage) {
+ MEM_freeN(storage);
+ stl->storage[i] = NULL;
+ }
+ }
+}
+
static void GPU_viewport_passes_free(GPUViewport *viewport)
{
PassList *psl = (PassList *)viewport->psl;
@@ -242,10 +269,12 @@ 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);
MEM_freeN(viewport->fbl);
MEM_freeN(viewport->txl);
MEM_freeN(viewport->psl);
+ MEM_freeN(viewport->stl);
}
/****************** debug ********************/