diff options
Diffstat (limited to 'source/blender/gpu/intern/gpu_material.c')
-rw-r--r-- | source/blender/gpu/intern/gpu_material.c | 95 |
1 files changed, 62 insertions, 33 deletions
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index c00baef2856..a08bef4472a 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -64,6 +64,7 @@ #include "GPU_material.h" #include "GPU_shader.h" #include "GPU_texture.h" +#include "GPU_uniformbuffer.h" #include "gpu_codegen.h" #include "gpu_lamp_private.h" @@ -101,7 +102,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 */ @@ -133,6 +134,7 @@ struct GPUMaterial { bool bound; bool is_opensubdiv; + GPUUniformBuffer *ubo; /* UBOs for shader uniforms. */ }; /* Forward declaration so shade_light_textures() can use this, while still keeping the code somewhat organized */ @@ -250,21 +252,10 @@ void GPU_material_free(ListBase *gpumaterial) if (material->pass) GPU_pass_free(material->pass); - for (LinkData *nlink = material->lamps.first; nlink; nlink = nlink->next) { - GPULamp *lamp = nlink->data; - - if (material->ma) { - Material *ma = material->ma; - - LinkData *next = NULL; - for (LinkData *mlink = lamp->materials.first; mlink; mlink = next) { - next = mlink->next; - if (mlink->data == ma) - BLI_freelinkN(&lamp->materials, mlink); - } - } + if (material->ubo != NULL) { + GPU_uniformbuffer_free(material->ubo); } - + BLI_freelistN(&material->lamps); MEM_freeN(material); @@ -289,8 +280,8 @@ void GPU_material_bind( for (LinkData *nlink = material->lamps.first; nlink; nlink = nlink->next) { GPULamp *lamp = nlink->data; - if (!lamp->hide && (lamp->lay & viewlay) && (!(lamp->mode & LA_LAYER) || (lamp->lay & oblay)) && - GPU_lamp_override_visible(lamp, srl, material->ma)) + if ((lamp->lay & viewlay) && (!(lamp->mode & LA_LAYER) || (lamp->lay & oblay)) && + GPU_lamp_visible(lamp, srl, material->ma)) { lamp->dynenergy = lamp->energy; copy_v3_v3(lamp->dyncol, lamp->col); @@ -444,6 +435,30 @@ GPUPass *GPU_material_get_pass(GPUMaterial *material) return material->pass; } +GPUUniformBuffer *GPU_material_get_uniform_buffer(GPUMaterial *material) +{ + return material->ubo; +} + +/** + * Create dynamic UBO from parameters + * \param ListBase of BLI_genericNodeN(GPUInput) + */ +void GPU_material_create_uniform_buffer(GPUMaterial *material, ListBase *inputs) +{ + material->ubo = GPU_uniformbuffer_dynamic_create(inputs, NULL); +} + +void GPU_material_uniform_buffer_tag_dirty(ListBase *gpumaterials) +{ + for (LinkData *link = gpumaterials->first; link; link = link->next) { + GPUMaterial *material = link->data; + if (material->ubo != NULL) { + GPU_uniformbuffer_tag_dirty(material->ubo); + } + } +} + void GPU_material_vertex_attributes(GPUMaterial *material, GPUVertexAttribs *attribs) { *attribs = material->attribs; @@ -904,14 +919,12 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la } add_user_list(&mat->lamps, lamp); - add_user_list(&lamp->materials, shi->gpumat->ma); return; } } } else if ((mat->scene->gm.flag & GAME_GLSL_NO_SHADOWS) && (lamp->mode & LA_ONLYSHADOW)) { add_user_list(&mat->lamps, lamp); - add_user_list(&lamp->materials, shi->gpumat->ma); return; } else @@ -978,7 +991,6 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la } add_user_list(&mat->lamps, lamp); - add_user_list(&lamp->materials, shi->gpumat->ma); } static void material_lights(GPUShadeInput *shi, GPUShadeResult *shr) @@ -2103,28 +2115,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); @@ -2132,7 +2159,8 @@ GPUMaterial *GPU_material_from_nodetree( /* Let Draw manager finish the construction. */ if (mat->outlink) { outlink = mat->outlink; - mat->pass = GPU_generate_pass_new(&mat->nodes, outlink, vert_code, geom_code, frag_lib, defines); + mat->pass = GPU_generate_pass_new( + mat, &mat->nodes, outlink, &mat->attribs, vert_code, geom_code, frag_lib, defines); } /* note that even if building the shader fails in some way, we still keep @@ -2273,7 +2301,6 @@ GPUNodeLink *GPU_lamp_get_data( /* ensure shadow buffer and lamp textures will be updated */ add_user_list(&mat->lamps, lamp); - add_user_list(&lamp->materials, mat->ma); return visifac; } @@ -2350,6 +2377,7 @@ GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma) case GPU_VEC4: case GPU_MAT3: case GPU_MAT4: + case GPU_CLOSURE: case GPU_ATTRIB: break; } @@ -2378,6 +2406,7 @@ GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma) break; case GPU_NONE: + case GPU_CLOSURE: case GPU_TEX2D: case GPU_TEXCUBE: case GPU_SHADOW2D: |