diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2017-02-08 23:44:13 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2017-02-09 13:25:51 +0300 |
commit | 6b372e3a22cbcdcb17a6239238189d6659418516 (patch) | |
tree | a756faafc16547d2d293e643634d22fa7a8075ac /source | |
parent | 09af91e0966afadd986a5a480e626698b2029826 (diff) |
Clay Engine: support for overrides (not working yet)
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/draw/engines/clay/clay.c | 269 | ||||
-rw-r--r-- | source/blender/draw/engines/clay/shaders/clay_frag.glsl | 4 | ||||
-rw-r--r-- | source/blender/draw/intern/DRW_render.h | 2 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 4 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_draw.c | 2 | ||||
-rw-r--r-- | source/blender/gpu/GPU_viewport.h | 9 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_viewport.c | 33 |
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 ********************/ |