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:
authorClément Foucault <foucault.clem@gmail.com>2018-03-05 02:54:31 +0300
committerClément Foucault <foucault.clem@gmail.com>2018-03-06 18:44:04 +0300
commit3a209c285754a08339c654d075b5d273fa264c08 (patch)
treebd1121dc7c095af648263e0dbef1b6cf76f7d4e5 /source/blender/gpu
parentf14cbc0d0773d33f917c75f84b25dbc1e48a2976 (diff)
DRW: Deferred compilation initial implementation.
Diffstat (limited to 'source/blender/gpu')
-rw-r--r--source/blender/gpu/GPU_material.h10
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c13
-rw-r--r--source/blender/gpu/intern/gpu_codegen.h3
-rw-r--r--source/blender/gpu/intern/gpu_material.c51
4 files changed, 60 insertions, 17 deletions
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index b486ff14dd1..14c2043ebad 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -144,6 +144,11 @@ typedef struct GPUNodeStack {
bool end;
} GPUNodeStack;
+typedef enum GPUMaterialSatus {
+ GPU_MAT_FAILED = 0,
+ GPU_MAT_QUEUED,
+ GPU_MAT_SUCCESS,
+} GPUMaterialSatus;
#define GPU_DYNAMIC_GROUP_FROM_TYPE(f) ((f) & 0xFFFF0000)
@@ -245,9 +250,11 @@ 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, const void *engine_type, int options,
- const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines);
+ const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines, bool deferred);
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);
+void GPU_material_generate_pass(
+ GPUMaterial *mat, const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines);
void GPU_material_free(struct ListBase *gpumaterial);
void GPU_materials_free(void);
@@ -263,6 +270,7 @@ bool GPU_material_bound(GPUMaterial *material);
struct Scene *GPU_material_scene(GPUMaterial *material);
GPUMatType GPU_Material_get_type(GPUMaterial *material);
struct GPUPass *GPU_material_get_pass(GPUMaterial *material);
+GPUMaterialSatus GPU_material_status(GPUMaterial *mat);
struct GPUUniformBuffer *GPU_material_get_uniform_buffer(GPUMaterial *material);
void GPU_material_create_uniform_buffer(GPUMaterial *material, struct ListBase *inputs);
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index ece78d4a5cf..b6f92497063 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -1720,7 +1720,7 @@ static void gpu_nodes_free(ListBase *nodes)
/* vertex attributes */
-static void gpu_nodes_get_vertex_attributes(ListBase *nodes, GPUVertexAttribs *attribs)
+void GPU_nodes_get_vertex_attributes(ListBase *nodes, GPUVertexAttribs *attribs)
{
GPUNode *node;
GPUInput *input;
@@ -2052,7 +2052,7 @@ static void gpu_nodes_tag(GPUNodeLink *link)
gpu_nodes_tag(input->link);
}
-static void gpu_nodes_prune(ListBase *nodes, GPUNodeLink *outlink)
+void GPU_nodes_prune(ListBase *nodes, GPUNodeLink *outlink)
{
GPUNode *node, *next;
@@ -2084,9 +2084,9 @@ GPUPass *GPU_generate_pass_new(
char *vertexcode, *geometrycode, *fragmentcode;
/* prune unused nodes */
- gpu_nodes_prune(nodes, frag_outlink);
+ GPU_nodes_prune(nodes, frag_outlink);
- gpu_nodes_get_vertex_attributes(nodes, attribs);
+ GPU_nodes_get_vertex_attributes(nodes, attribs);
/* generate code and compile with opengl */
fragmentgen = code_generate_fragment(material, nodes, frag_outlink->output, true);
@@ -2135,7 +2135,6 @@ GPUPass *GPU_generate_pass_new(
/* extract dynamic inputs and throw away nodes */
gpu_nodes_extract_dynamic_inputs_new(pass, nodes);
- gpu_nodes_free(nodes);
MEM_freeN(fragmentgen);
MEM_freeN(vertexgen);
@@ -2162,9 +2161,9 @@ GPUPass *GPU_generate_pass(
#endif
/* prune unused nodes */
- gpu_nodes_prune(nodes, outlink);
+ GPU_nodes_prune(nodes, outlink);
- gpu_nodes_get_vertex_attributes(nodes, attribs);
+ GPU_nodes_get_vertex_attributes(nodes, attribs);
gpu_nodes_get_builtin_flag(nodes, builtins);
/* generate code and compile with opengl */
diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h
index 14e07a6e012..0f8218c9c15 100644
--- a/source/blender/gpu/intern/gpu_codegen.h
+++ b/source/blender/gpu/intern/gpu_codegen.h
@@ -183,6 +183,9 @@ GPUPass *GPU_generate_pass(
struct GPUShader *GPU_pass_shader(GPUPass *pass);
+void GPU_nodes_get_vertex_attributes(ListBase *nodes, struct GPUVertexAttribs *attribs);
+void GPU_nodes_prune(ListBase *nodes, struct GPUNodeLink *outlink);
+
void GPU_pass_bind(GPUPass *pass, double time, int mipmap);
void GPU_pass_update_uniforms(GPUPass *pass);
void GPU_pass_unbind(GPUPass *pass);
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 2d7b9415030..4d888824f97 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -68,6 +68,8 @@
#include "GPU_texture.h"
#include "GPU_uniformbuffer.h"
+#include "DRW_engine.h"
+
#include "gpu_codegen.h"
#include "gpu_lamp_private.h"
@@ -103,6 +105,7 @@ struct GPUMaterial {
/* material for mesh surface, worlds or something else.
* some code generation is done differently depending on the use case */
int type; /* DEPRECATED */
+ GPUMaterialSatus status;
const void *engine_type; /* attached engine type */
int options; /* to identify shader variations (shadow, probe, world background...) */
@@ -142,7 +145,10 @@ struct GPUMaterial {
*/
int domain;
+ /* Used by 2.8 pipeline */
GPUUniformBuffer *ubo; /* UBOs for shader uniforms. */
+
+ /* Eevee SSS */
GPUUniformBuffer *sss_profile; /* UBO containing SSS profile. */
GPUTexture *sss_tex_profile; /* Texture containing SSS profile. */
float *sss_radii; /* UBO containing SSS profile. */
@@ -221,6 +227,8 @@ static int gpu_material_construct_end(GPUMaterial *material, const char *passnam
material->is_opensubdiv,
GPU_material_use_new_shading_nodes(material));
+ material->status = (material->pass) ? GPU_MAT_SUCCESS : GPU_MAT_FAILED;
+
if (!material->pass)
return 0;
@@ -270,6 +278,11 @@ void GPU_material_free(ListBase *gpumaterial)
for (LinkData *link = gpumaterial->first; link; link = link->next) {
GPUMaterial *material = link->data;
+ /* Cancel / wait any pending lazy compilation. */
+ DRW_deferred_shader_remove(material);
+
+ GPU_pass_free_nodes(&material->nodes);
+
if (material->pass)
GPU_pass_free(material->pass);
@@ -829,6 +842,12 @@ void gpu_material_add_node(GPUMaterial *material, GPUNode *node)
BLI_addtail(&material->nodes, node);
}
+/* Return true if the material compilation has not yet begin or begin. */
+GPUMaterialSatus GPU_material_status(GPUMaterial *mat)
+{
+ return mat->status;
+}
+
/* Code generation */
bool GPU_material_do_color_management(GPUMaterial *mat)
@@ -2490,10 +2509,8 @@ GPUMaterial *GPU_material_from_nodetree_find(
*/
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)
+ const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines, bool deferred)
{
- GPUMaterial *mat;
- GPUNodeLink *outlink;
LinkData *link;
bool has_volume_output, has_surface_output;
@@ -2501,7 +2518,7 @@ GPUMaterial *GPU_material_from_nodetree(
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 */
+ GPUMaterial *mat = MEM_callocN(sizeof(GPUMaterial), "GPUMaterial");;
mat->scene = scene;
mat->engine_type = engine_type;
mat->options = options;
@@ -2516,11 +2533,15 @@ GPUMaterial *GPU_material_from_nodetree(
mat->domain |= GPU_DOMAIN_VOLUME;
}
- /* Let Draw manager finish the construction. */
- if (mat->outlink) {
- outlink = mat->outlink;
- mat->pass = GPU_generate_pass_new(
- mat, &mat->nodes, outlink, &mat->attribs, vert_code, geom_code, frag_lib, defines);
+ if (!deferred) {
+ GPU_material_generate_pass(mat, vert_code, geom_code, frag_lib, defines);
+ }
+ else if (mat->outlink) {
+ /* Prune the unused nodes and extract attribs before compiling so the
+ * generated VBOs are ready to accept the future shader. */
+ GPU_nodes_prune(&mat->nodes, mat->outlink);
+ GPU_nodes_get_vertex_attributes(&mat->nodes, &mat->attribs);
+ mat->status = GPU_MAT_QUEUED;
}
/* note that even if building the shader fails in some way, we still keep
@@ -2534,6 +2555,18 @@ GPUMaterial *GPU_material_from_nodetree(
return mat;
}
+/* Calls this function if /a mat was created with deferred compilation. */
+void GPU_material_generate_pass(
+ GPUMaterial *mat, const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines)
+{
+ BLI_assert(mat->pass == NULL); /* Only run once! */
+ if (mat->outlink) {
+ mat->pass = GPU_generate_pass_new(
+ mat, &mat->nodes, mat->outlink, &mat->attribs, vert_code, geom_code, frag_lib, defines);
+ mat->status = (mat->pass) ? GPU_MAT_SUCCESS : GPU_MAT_FAILED;
+ }
+}
+
GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma, bool use_opensubdiv)
{
GPUMaterial *mat;