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_material.c')
-rw-r--r--source/blender/gpu/intern/gpu_material.c95
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: