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>2017-06-28 22:05:43 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-06-28 22:05:43 +0300
commitada6e720f941dbd50e75b04feea6dae16b8ffc55 (patch)
treef5bb643796be47860bf7ffec1c71a7156cbba9f7 /source/blender/gpu
parent26b699a105acf47a66f14fe40539b471b409ecc0 (diff)
GPU_codegen: Add support for passing attributes through the geometry stage.
Should fix some issues with missing attributes in Eevee.
Diffstat (limited to 'source/blender/gpu')
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c79
1 files changed, 63 insertions, 16 deletions
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 8586ee67d5d..afdb927fbcc 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -787,7 +787,7 @@ static const char *attrib_prefix_get(CustomDataType type)
}
}
-static char *code_generate_vertex_new(ListBase *nodes, const char *vert_code)
+static char *code_generate_vertex_new(ListBase *nodes, const char *vert_code, bool use_geom)
{
DynStr *ds = BLI_dynstr_new();
GPUNode *node;
@@ -814,8 +814,8 @@ static char *code_generate_vertex_new(ListBase *nodes, const char *vert_code)
BLI_dynstr_appendf(ds, "#define att%d %s%u\n",
input->attribid, attrib_prefix_get(input->attribtype), hash);
}
- BLI_dynstr_appendf(ds, "out %s var%d;\n",
- GPU_DATATYPE_STR[input->type], input->attribid);
+ BLI_dynstr_appendf(ds, "out %s var%d%s;\n",
+ GPU_DATATYPE_STR[input->type], input->attribid, use_geom ? "g" : "");
}
}
}
@@ -831,19 +831,19 @@ static char *code_generate_vertex_new(ListBase *nodes, const char *vert_code)
if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
if (input->attribtype == CD_TANGENT) { /* silly exception */
BLI_dynstr_appendf(
- ds, "\tvar%d.xyz = normalize(NormalMatrix * att%d.xyz);\n",
- input->attribid, input->attribid);
+ ds, "\tvar%d%s.xyz = normalize(NormalMatrix * att%d.xyz);\n",
+ input->attribid, use_geom ? "g" : "", input->attribid);
BLI_dynstr_appendf(
- ds, "\tvar%d.w = att%d.w;\n",
- input->attribid, input->attribid);
+ ds, "\tvar%d%s.w = att%d.w;\n",
+ input->attribid, use_geom ? "g" : "", input->attribid);
}
else if (input->attribtype == CD_ORCO) {
- BLI_dynstr_appendf(ds, "\tvar%d = OrcoTexCoFactors[0] + position * OrcoTexCoFactors[1];\n",
- input->attribid);
+ BLI_dynstr_appendf(ds, "\tvar%d%s = OrcoTexCoFactors[0] + position * OrcoTexCoFactors[1];\n",
+ input->attribid, use_geom ? "g" : "");
}
else {
- BLI_dynstr_appendf(ds, "\tvar%d = att%d;\n",
- input->attribid, input->attribid);
+ BLI_dynstr_appendf(ds, "\tvar%d%s = att%d;\n",
+ input->attribid, use_geom ? "g" : "", input->attribid);
}
}
}
@@ -972,6 +972,49 @@ static char *code_generate_vertex(ListBase *nodes, const GPUMatType type)
return code;
}
+static char *code_generate_geometry_new(ListBase *nodes, const char *geom_code)
+{
+ DynStr *ds = BLI_dynstr_new();
+ GPUNode *node;
+ GPUInput *input;
+ char *code;
+
+ /* Generate varying declarations. */
+ for (node = nodes->first; node; node = node->next) {
+ for (input = node->inputs.first; input; input = input->next) {
+ if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
+ if (input->attribtype == CD_MTFACE) {
+ BLI_dynstr_appendf(ds, "in %s var%dg[];\n",
+ GPU_DATATYPE_STR[input->type],
+ input->attribid);
+ BLI_dynstr_appendf(ds, "out %s var%d;\n",
+ GPU_DATATYPE_STR[input->type],
+ input->attribid);
+ }
+ }
+ }
+ }
+ /* Generate varying assignments. */
+ BLI_dynstr_append(ds, "#define ATTRIB\n");
+ BLI_dynstr_appendf(ds, "void pass_attrib(in int vert) {\n");
+ for (node = nodes->first; node; node = node->next) {
+ for (input = node->inputs.first; input; input = input->next) {
+ if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
+ /* TODO let shader choose what to do depending on what the attrib is. */
+ BLI_dynstr_appendf(ds, "\tvar%d = var%dg[vert];", input->attribid, input->attribid);
+ }
+ }
+ }
+ BLI_dynstr_append(ds, "}\n");
+
+ BLI_dynstr_append(ds, geom_code);
+
+ code = BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
+
+ return code;
+}
+
static char *code_generate_geometry(ListBase *nodes, bool use_opensubdiv)
{
#ifdef WITH_OPENSUBDIV
@@ -1854,7 +1897,7 @@ GPUPass *GPU_generate_pass_new(
{
GPUShader *shader;
GPUPass *pass;
- char *vertexgen, *geometrygen, *fragmentgen, *tmp;
+ char *vertexgen, *fragmentgen, *tmp;
char *vertexcode, *geometrycode, *fragmentcode;
/* prune unused nodes */
@@ -1864,14 +1907,18 @@ GPUPass *GPU_generate_pass_new(
/* generate code and compile with opengl */
fragmentgen = code_generate_fragment(nodes, frag_outlink->output, true);
- vertexgen = code_generate_vertex_new(nodes, vert_code);
- // geometrygen = code_generate_geometry(nodes, false);
- UNUSED_VARS(geometrygen);
+ vertexgen = code_generate_vertex_new(nodes, vert_code, (geom_code != NULL));
tmp = BLI_strdupcat(frag_lib, glsl_material_library);
fragmentcode = BLI_strdupcat(tmp, fragmentgen);
vertexcode = BLI_strdup(vertexgen);
- geometrycode = (geom_code) ? BLI_strdup(geom_code) : NULL;
+
+ if (geom_code) {
+ geometrycode = code_generate_geometry_new(nodes, geom_code);
+ }
+ else {
+ geometrycode = NULL;
+ }
shader = GPU_shader_create(vertexcode,
fragmentcode,