diff options
author | Campbell Barton <ideasman42@gmail.com> | 2017-06-28 03:50:33 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2017-06-28 03:59:25 +0300 |
commit | 87dd9c31a01e734964f3d3657cd9f1ae8706cf7b (patch) | |
tree | d53bd9a8dac460d232306211f9c478a8286787e5 | |
parent | 037876659f473b7a7e14bdd300b7285a22ef095b (diff) |
GPU: split GPU_material_from_nodetree in two
Add GPU_material_from_nodetree_find to avoid having to construct other
arguments which won't be used in the case the material is exists.
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_materials.c | 58 | ||||
-rw-r--r-- | source/blender/gpu/GPU_material.h | 4 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_material.c | 39 |
3 files changed, 68 insertions, 33 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index 74cb6b0d7a0..7bc45bf62e3 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -351,40 +351,55 @@ void EEVEE_materials_init(void) struct GPUMaterial *EEVEE_material_world_lightprobe_get(struct Scene *scene, World *wo) { + const void *engine = &DRW_engine_viewport_eevee_type; + const int options = VAR_WORLD_PROBE; + + GPUMaterial *mat = GPU_material_from_nodetree_find(&wo->gpumaterial, engine, options); + if (mat != NULL) { + return mat; + } return GPU_material_from_nodetree( - scene, wo->nodetree, &wo->gpumaterial, &DRW_engine_viewport_eevee_type, - VAR_WORLD_PROBE, - datatoc_lightprobe_vert_glsl, datatoc_lightprobe_geom_glsl, e_data.frag_shader_lib, - SHADER_DEFINES "#define PROBE_CAPTURE\n"); + scene, wo->nodetree, &wo->gpumaterial, engine, options, + datatoc_lightprobe_vert_glsl, datatoc_lightprobe_geom_glsl, e_data.frag_shader_lib, + SHADER_DEFINES "#define PROBE_CAPTURE\n"); } struct GPUMaterial *EEVEE_material_world_background_get(struct Scene *scene, World *wo) { + const void *engine = &DRW_engine_viewport_eevee_type; + int options = VAR_WORLD_BACKGROUND; + + GPUMaterial *mat = GPU_material_from_nodetree_find(&wo->gpumaterial, engine, options); + if (mat != NULL) { + return mat; + } return GPU_material_from_nodetree( - scene, wo->nodetree, &wo->gpumaterial, &DRW_engine_viewport_eevee_type, - VAR_WORLD_BACKGROUND, - datatoc_background_vert_glsl, NULL, e_data.frag_shader_lib, - SHADER_DEFINES "#define WORLD_BACKGROUND\n"); + scene, wo->nodetree, &wo->gpumaterial, engine, options, + datatoc_background_vert_glsl, NULL, e_data.frag_shader_lib, + SHADER_DEFINES "#define WORLD_BACKGROUND\n"); } struct GPUMaterial *EEVEE_material_mesh_get( struct Scene *scene, Material *ma, bool use_ao, bool use_bent_normals) { - struct GPUMaterial *mat; - + const void *engine = &DRW_engine_viewport_eevee_type; int options = VAR_MAT_MESH; if (use_ao) options |= VAR_MAT_AO; if (use_bent_normals) options |= VAR_MAT_BENT; + GPUMaterial *mat = GPU_material_from_nodetree_find(&ma->gpumaterial, engine, options); + if (mat) { + return mat; + } + char *defines = eevee_get_defines(options); mat = GPU_material_from_nodetree( - scene, ma->nodetree, &ma->gpumaterial, &DRW_engine_viewport_eevee_type, - options, - datatoc_lit_surface_vert_glsl, NULL, e_data.frag_shader_lib, - defines); + scene, ma->nodetree, &ma->gpumaterial, engine, options, + datatoc_lit_surface_vert_glsl, NULL, e_data.frag_shader_lib, + defines); MEM_freeN(defines); @@ -395,20 +410,23 @@ struct GPUMaterial *EEVEE_material_hair_get( struct Scene *scene, Material *ma, bool use_ao, bool use_bent_normals) { - struct GPUMaterial *mat; - + const void *engine = &DRW_engine_viewport_eevee_type; int options = VAR_MAT_MESH | VAR_MAT_HAIR; if (use_ao) options |= VAR_MAT_AO; if (use_bent_normals) options |= VAR_MAT_BENT; + GPUMaterial *mat = GPU_material_from_nodetree_find(&ma->gpumaterial, engine, options); + if (mat) { + return mat; + } + char *defines = eevee_get_defines(options); mat = GPU_material_from_nodetree( - scene, ma->nodetree, &ma->gpumaterial, &DRW_engine_viewport_eevee_type, - options, - datatoc_lit_surface_vert_glsl, NULL, e_data.frag_shader_lib, - defines); + scene, ma->nodetree, &ma->gpumaterial, engine, options, + datatoc_lit_surface_vert_glsl, NULL, e_data.frag_shader_lib, + defines); MEM_freeN(defines); diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 4345a31839a..b12a59f607d 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -219,8 +219,10 @@ GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, float obcol[4]); /* High level functions to create and use GPU materials */ GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo); +GPUMaterial *GPU_material_from_nodetree_find( + struct ListBase *gpumaterials, const void *engine_type, int options); GPUMaterial *GPU_material_from_nodetree( - struct Scene *scene, struct bNodeTree *ntree, struct ListBase *gpumaterials, void *engine_type, int options, + struct Scene *scene, struct bNodeTree *ntree, struct ListBase *gpumaterials, const void *engine_type, int options, const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines); GPUMaterial *GPU_material_from_blender(struct Scene *scene, struct Material *ma, bool use_opensubdiv); GPUMaterial *GPU_material_matcap(struct Scene *scene, struct Material *ma, bool use_opensubdiv); diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 15253477c7c..dafd305e8ba 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -101,7 +101,7 @@ struct GPUMaterial { * some code generation is done differently depending on the use case */ int type; /* DEPRECATED */ - void *engine; /* attached engine type */ + const void *engine_type; /* attached engine type */ int options; /* to identify shader variations (shadow, probe, world background...) */ /* for creating the material */ @@ -2103,28 +2103,43 @@ GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo) return mat; } -/* TODO : This is supposed to replace GPU_material_from_blender/_world in the future */ -GPUMaterial *GPU_material_from_nodetree( - Scene *scene, struct bNodeTree *ntree, ListBase *gpumaterials, void *engine_type, int options, - const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines) +GPUMaterial *GPU_material_from_nodetree_find( + ListBase *gpumaterials, const void *engine_type, int options) { - GPUMaterial *mat; - GPUNodeLink *outlink; - LinkData *link; - - for (link = gpumaterials->first; link; link = link->next) { + for (LinkData *link = gpumaterials->first; link; link = link->next) { GPUMaterial *current_material = (GPUMaterial *)link->data; - if (current_material->engine == engine_type && + if (current_material->engine_type == engine_type && current_material->options == options) { return current_material; } } + return NULL; +} + +/** + * TODO: This is supposed to replace GPU_material_from_blender/_world in the future + * + * \note Caller must use #GPU_material_from_nodetree_find to re-use existing materials, + * This is enforced since constructing other arguments to this function may be expensive + * so only do this when they are needed. + */ +GPUMaterial *GPU_material_from_nodetree( + Scene *scene, struct bNodeTree *ntree, ListBase *gpumaterials, const void *engine_type, int options, + const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines) +{ + GPUMaterial *mat; + GPUNodeLink *outlink; + LinkData *link; + + /* Caller must re-use materials. */ + BLI_assert(GPU_material_from_nodetree_find(gpumaterials, engine_type, options) == NULL); + /* allocate material */ mat = GPU_material_construct_begin(NULL); /* TODO remove GPU_material_construct_begin */ mat->scene = scene; - mat->engine = engine_type; + mat->engine_type = engine_type; mat->options = options; ntreeGPUMaterialNodes(ntree, mat, NODE_NEWER_SHADING); |