Changeset View
Changeset View
Standalone View
Standalone View
source/blender/gpu/intern/gpu_codegen.c
| Show First 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | |||||
| static GPUPass *pass_cache = NULL; | static GPUPass *pass_cache = NULL; | ||||
| static SpinLock pass_cache_spin; | static SpinLock pass_cache_spin; | ||||
| static uint32_t gpu_pass_hash(const char *frag_gen, const char *defs, ListBase *attributes) | static uint32_t gpu_pass_hash(const char *frag_gen, const char *defs, ListBase *attributes) | ||||
| { | { | ||||
| BLI_HashMurmur2A hm2a; | BLI_HashMurmur2A hm2a; | ||||
| BLI_hash_mm2a_init(&hm2a, 0); | BLI_hash_mm2a_init(&hm2a, 0); | ||||
| BLI_hash_mm2a_add(&hm2a, (uchar *)frag_gen, strlen(frag_gen)); | BLI_hash_mm2a_add(&hm2a, (uchar *)frag_gen, strlen(frag_gen)); | ||||
| for (GPUMaterialAttribute *attr = attributes->first; attr; attr = attr->next) { | LISTBASE_FOREACH (GPUMaterialAttribute *, attr, attributes) { | ||||
| BLI_hash_mm2a_add(&hm2a, (uchar *)attr->name, strlen(attr->name)); | BLI_hash_mm2a_add(&hm2a, (uchar *)attr->name, strlen(attr->name)); | ||||
| } | } | ||||
| if (defs) { | if (defs) { | ||||
| BLI_hash_mm2a_add(&hm2a, (uchar *)defs, strlen(defs)); | BLI_hash_mm2a_add(&hm2a, (uchar *)defs, strlen(defs)); | ||||
| } | } | ||||
| return BLI_hash_mm2a_end(&hm2a); | return BLI_hash_mm2a_end(&hm2a); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 222 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| GPUNode *node; | GPUNode *node; | ||||
| GPUInput *input; | GPUInput *input; | ||||
| const char *name; | const char *name; | ||||
| int builtins = 0; | int builtins = 0; | ||||
| ListBase ubo_inputs = {NULL, NULL}; | ListBase ubo_inputs = {NULL, NULL}; | ||||
| /* Attributes */ | /* Attributes */ | ||||
| for (GPUMaterialAttribute *attr = graph->attributes.first; attr; attr = attr->next) { | LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) { | ||||
| BLI_dynstr_appendf(ds, "in %s var%d;\n", gpu_data_type_to_string(attr->gputype), attr->id); | BLI_dynstr_appendf(ds, "in %s var%d;\n", gpu_data_type_to_string(attr->gputype), attr->id); | ||||
| } | } | ||||
| /* Textures */ | /* Textures */ | ||||
| for (GPUMaterialTexture *tex = graph->textures.first; tex; tex = tex->next) { | LISTBASE_FOREACH (GPUMaterialTexture *, tex, &graph->textures) { | ||||
| if (tex->colorband) { | if (tex->colorband) { | ||||
| BLI_dynstr_appendf(ds, "uniform sampler1DArray %s;\n", tex->sampler_name); | BLI_dynstr_appendf(ds, "uniform sampler1DArray %s;\n", tex->sampler_name); | ||||
| } | } | ||||
| else if (tex->tiled_mapping_name[0]) { | else if (tex->tiled_mapping_name[0]) { | ||||
| BLI_dynstr_appendf(ds, "uniform sampler2DArray %s;\n", tex->sampler_name); | BLI_dynstr_appendf(ds, "uniform sampler2DArray %s;\n", tex->sampler_name); | ||||
| BLI_dynstr_appendf(ds, "uniform sampler1DArray %s;\n", tex->tiled_mapping_name); | BLI_dynstr_appendf(ds, "uniform sampler1DArray %s;\n", tex->tiled_mapping_name); | ||||
| } | } | ||||
| else { | else { | ||||
| BLI_dynstr_appendf(ds, "uniform sampler2D %s;\n", tex->sampler_name); | BLI_dynstr_appendf(ds, "uniform sampler2D %s;\n", tex->sampler_name); | ||||
| } | } | ||||
| } | } | ||||
| /* Volume Grids */ | /* Volume Grids */ | ||||
| for (GPUMaterialVolumeGrid *grid = graph->volume_grids.first; grid; grid = grid->next) { | LISTBASE_FOREACH (GPUMaterialVolumeGrid *, grid, &graph->volume_grids) { | ||||
| BLI_dynstr_appendf(ds, "uniform sampler3D %s;\n", grid->sampler_name); | BLI_dynstr_appendf(ds, "uniform sampler3D %s;\n", grid->sampler_name); | ||||
| BLI_dynstr_appendf(ds, "uniform mat4 %s = mat4(0.0);\n", grid->transform_name); | BLI_dynstr_appendf(ds, "uniform mat4 %s = mat4(0.0);\n", grid->transform_name); | ||||
| } | } | ||||
| /* Print other uniforms */ | /* Print other uniforms */ | ||||
| for (node = graph->nodes.first; node; node = node->next) { | for (node = graph->nodes.first; node; node = node->next) { | ||||
| for (input = node->inputs.first; input; input = input->next) { | for (input = node->inputs.first; input; input = input->next) { | ||||
| if (input->source == GPU_SOURCE_BUILTIN) { | if (input->source == GPU_SOURCE_BUILTIN) { | ||||
| Show All 31 Lines | static int codegen_process_uniforms_functions(GPUMaterial *material, | ||||
| /* Handle the UBO block separately. */ | /* Handle the UBO block separately. */ | ||||
| if ((material != NULL) && !BLI_listbase_is_empty(&ubo_inputs)) { | if ((material != NULL) && !BLI_listbase_is_empty(&ubo_inputs)) { | ||||
| GPU_material_uniform_buffer_create(material, &ubo_inputs); | GPU_material_uniform_buffer_create(material, &ubo_inputs); | ||||
| /* Inputs are sorted */ | /* Inputs are sorted */ | ||||
| BLI_dynstr_appendf(ds, "\nlayout (std140) uniform %s {\n", GPU_UBO_BLOCK_NAME); | BLI_dynstr_appendf(ds, "\nlayout (std140) uniform %s {\n", GPU_UBO_BLOCK_NAME); | ||||
| for (LinkData *link = ubo_inputs.first; link; link = link->next) { | LISTBASE_FOREACH (LinkData *, link, &ubo_inputs) { | ||||
| input = link->data; | input = link->data; | ||||
| BLI_dynstr_appendf(ds, "\t%s unf%d;\n", gpu_data_type_to_string(input->type), input->id); | BLI_dynstr_appendf(ds, "\t%s unf%d;\n", gpu_data_type_to_string(input->type), input->id); | ||||
| } | } | ||||
| BLI_dynstr_append(ds, "};\n"); | BLI_dynstr_append(ds, "};\n"); | ||||
| BLI_freelistN(&ubo_inputs); | BLI_freelistN(&ubo_inputs); | ||||
| } | } | ||||
| BLI_dynstr_append(ds, "\n"); | BLI_dynstr_append(ds, "\n"); | ||||
| ▲ Show 20 Lines • Show All 275 Lines • ▼ Show 20 Lines | static char *code_generate_vertex(GPUNodeGraph *graph, const char *vert_code, bool use_geom) | ||||
| /* Hairs uv and col attributes are passed by bufferTextures. */ | /* Hairs uv and col attributes are passed by bufferTextures. */ | ||||
| BLI_dynstr_append(ds, | BLI_dynstr_append(ds, | ||||
| "#ifdef HAIR_SHADER\n" | "#ifdef HAIR_SHADER\n" | ||||
| "#define DEFINE_ATTR(type, attr) uniform samplerBuffer attr\n" | "#define DEFINE_ATTR(type, attr) uniform samplerBuffer attr\n" | ||||
| "#else\n" | "#else\n" | ||||
| "#define DEFINE_ATTR(type, attr) in type attr\n" | "#define DEFINE_ATTR(type, attr) in type attr\n" | ||||
| "#endif\n"); | "#endif\n"); | ||||
| for (GPUMaterialAttribute *attr = graph->attributes.first; attr; attr = attr->next) { | LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) { | ||||
| /* XXX FIXME : see notes in mesh_render_data_create() */ | /* XXX FIXME : see notes in mesh_render_data_create() */ | ||||
| /* NOTE : Replicate changes to mesh_render_data_create() in draw_cache_impl_mesh.c */ | /* NOTE : Replicate changes to mesh_render_data_create() in draw_cache_impl_mesh.c */ | ||||
| if (attr->type == CD_ORCO) { | if (attr->type == CD_ORCO) { | ||||
| /* OPTI : orco is computed from local positions, but only if no modifier is present. */ | /* OPTI : orco is computed from local positions, but only if no modifier is present. */ | ||||
| BLI_dynstr_append(ds, datatoc_gpu_shader_common_obinfos_lib_glsl); | BLI_dynstr_append(ds, datatoc_gpu_shader_common_obinfos_lib_glsl); | ||||
| BLI_dynstr_append(ds, "DEFINE_ATTR(vec4, orco);\n"); | BLI_dynstr_append(ds, "DEFINE_ATTR(vec4, orco);\n"); | ||||
| } | } | ||||
| else if (attr->name[0] == '\0') { | else if (attr->name[0] == '\0') { | ||||
| ▲ Show 20 Lines • Show All 97 Lines • ▼ Show 20 Lines | if (builtins & GPU_BARYCENTRIC_TEXCO) { | ||||
| BLI_dynstr_appendf( | BLI_dynstr_appendf( | ||||
| ds, "\tbarycentricTexCo%s.y = float(((_base_id %% 4) %% 3) > 0);\n", use_geom ? "g" : ""); | ds, "\tbarycentricTexCo%s.y = float(((_base_id %% 4) %% 3) > 0);\n", use_geom ? "g" : ""); | ||||
| } | } | ||||
| if (builtins & GPU_BARYCENTRIC_DIST) { | if (builtins & GPU_BARYCENTRIC_DIST) { | ||||
| BLI_dynstr_append(ds, "\tbarycentricPosg = position;\n"); | BLI_dynstr_append(ds, "\tbarycentricPosg = position;\n"); | ||||
| } | } | ||||
| for (GPUMaterialAttribute *attr = graph->attributes.first; attr; attr = attr->next) { | LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) { | ||||
| if (attr->type == CD_TANGENT) { | if (attr->type == CD_TANGENT) { | ||||
| /* Not supported by hairs */ | /* Not supported by hairs */ | ||||
| BLI_dynstr_appendf(ds, "\tvar%d%s = vec4(0.0);\n", attr->id, use_geom ? "g" : ""); | BLI_dynstr_appendf(ds, "\tvar%d%s = vec4(0.0);\n", attr->id, use_geom ? "g" : ""); | ||||
| } | } | ||||
| else if (attr->type == CD_ORCO) { | else if (attr->type == CD_ORCO) { | ||||
| BLI_dynstr_appendf(ds, | BLI_dynstr_appendf(ds, | ||||
| "\tvar%d%s = OrcoTexCoFactors[0].xyz + (ModelMatrixInverse * " | "\tvar%d%s = OrcoTexCoFactors[0].xyz + (ModelMatrixInverse * " | ||||
| "vec4(hair_get_strand_pos(), 1.0)).xyz * OrcoTexCoFactors[1].xyz;\n", | "vec4(hair_get_strand_pos(), 1.0)).xyz * OrcoTexCoFactors[1].xyz;\n", | ||||
| Show All 16 Lines | static char *code_generate_vertex(GPUNodeGraph *graph, const char *vert_code, bool use_geom) | ||||
| /* GPU_BARYCENTRIC_TEXCO cannot be computed based on gl_VertexID | /* GPU_BARYCENTRIC_TEXCO cannot be computed based on gl_VertexID | ||||
| * for MESH_SHADER because of indexed drawing. In this case a | * for MESH_SHADER because of indexed drawing. In this case a | ||||
| * geometry shader is needed. */ | * geometry shader is needed. */ | ||||
| if (builtins & GPU_BARYCENTRIC_DIST) { | if (builtins & GPU_BARYCENTRIC_DIST) { | ||||
| BLI_dynstr_append(ds, "\tbarycentricPosg = (ModelMatrix * vec4(position, 1.0)).xyz;\n"); | BLI_dynstr_append(ds, "\tbarycentricPosg = (ModelMatrix * vec4(position, 1.0)).xyz;\n"); | ||||
| } | } | ||||
| for (GPUMaterialAttribute *attr = graph->attributes.first; attr; attr = attr->next) { | LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) { | ||||
| if (attr->type == CD_TANGENT) { /* silly exception */ | if (attr->type == CD_TANGENT) { /* silly exception */ | ||||
| BLI_dynstr_appendf(ds, | BLI_dynstr_appendf(ds, | ||||
| "\tvar%d%s.xyz = transpose(mat3(ModelMatrixInverse)) * att%d.xyz;\n", | "\tvar%d%s.xyz = transpose(mat3(ModelMatrixInverse)) * att%d.xyz;\n", | ||||
| attr->id, | attr->id, | ||||
| use_geom ? "g" : "", | use_geom ? "g" : "", | ||||
| attr->id); | attr->id); | ||||
| BLI_dynstr_appendf(ds, "\tvar%d%s.w = att%d.w;\n", attr->id, use_geom ? "g" : "", attr->id); | BLI_dynstr_appendf(ds, "\tvar%d%s.w = att%d.w;\n", attr->id, use_geom ? "g" : "", attr->id); | ||||
| /* Normalize only if vector is not null. */ | /* Normalize only if vector is not null. */ | ||||
| ▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | static char *code_generate_geometry(GPUNodeGraph *graph, | ||||
| for (node = graph->nodes.first; node; node = node->next) { | for (node = graph->nodes.first; node; node = node->next) { | ||||
| for (input = node->inputs.first; input; input = input->next) { | for (input = node->inputs.first; input; input = input->next) { | ||||
| if (input->source == GPU_SOURCE_BUILTIN) { | if (input->source == GPU_SOURCE_BUILTIN) { | ||||
| builtins |= input->builtin; | builtins |= input->builtin; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| for (GPUMaterialAttribute *attr = graph->attributes.first; attr; attr = attr->next) { | LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) { | ||||
| BLI_dynstr_appendf(ds, "in %s var%dg[];\n", gpu_data_type_to_string(attr->gputype), attr->id); | BLI_dynstr_appendf(ds, "in %s var%dg[];\n", gpu_data_type_to_string(attr->gputype), attr->id); | ||||
| BLI_dynstr_appendf(ds, "out %s var%d;\n", gpu_data_type_to_string(attr->gputype), attr->id); | BLI_dynstr_appendf(ds, "out %s var%d;\n", gpu_data_type_to_string(attr->gputype), attr->id); | ||||
| } | } | ||||
| if (builtins & GPU_BARYCENTRIC_TEXCO) { | if (builtins & GPU_BARYCENTRIC_TEXCO) { | ||||
| BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n"); | BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n"); | ||||
| BLI_dynstr_append(ds, "in vec2 barycentricTexCog[];\n"); | BLI_dynstr_append(ds, "in vec2 barycentricTexCog[];\n"); | ||||
| BLI_dynstr_append(ds, "#endif\n"); | BLI_dynstr_append(ds, "#endif\n"); | ||||
| ▲ Show 20 Lines • Show All 90 Lines • ▼ Show 20 Lines | if (builtins & GPU_BARYCENTRIC_TEXCO) { | ||||
| BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n"); | BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n"); | ||||
| BLI_dynstr_append(ds, "\tbarycentricTexCo = barycentricTexCog[vert];\n"); | BLI_dynstr_append(ds, "\tbarycentricTexCo = barycentricTexCog[vert];\n"); | ||||
| BLI_dynstr_append(ds, "#else\n"); | BLI_dynstr_append(ds, "#else\n"); | ||||
| BLI_dynstr_append(ds, "\tbarycentricTexCo.x = float((vert % 3) == 0);\n"); | BLI_dynstr_append(ds, "\tbarycentricTexCo.x = float((vert % 3) == 0);\n"); | ||||
| BLI_dynstr_append(ds, "\tbarycentricTexCo.y = float((vert % 3) == 1);\n"); | BLI_dynstr_append(ds, "\tbarycentricTexCo.y = float((vert % 3) == 1);\n"); | ||||
| BLI_dynstr_append(ds, "#endif\n"); | BLI_dynstr_append(ds, "#endif\n"); | ||||
| } | } | ||||
| for (GPUMaterialAttribute *attr = graph->attributes.first; attr; attr = attr->next) { | LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) { | ||||
| /* TODO let shader choose what to do depending on what the attribute is. */ | /* TODO let shader choose what to do depending on what the attribute is. */ | ||||
| BLI_dynstr_appendf(ds, "\tvar%d = var%dg[vert];\n", attr->id, attr->id); | BLI_dynstr_appendf(ds, "\tvar%d = var%dg[vert];\n", attr->id, attr->id); | ||||
| } | } | ||||
| BLI_dynstr_append(ds, "}\n"); | BLI_dynstr_append(ds, "}\n"); | ||||
| code = BLI_dynstr_get_cstring(ds); | code = BLI_dynstr_get_cstring(ds); | ||||
| BLI_dynstr_free(ds); | BLI_dynstr_free(ds); | ||||
| ▲ Show 20 Lines • Show All 305 Lines • Show Last 20 Lines | |||||