Changeset View
Changeset View
Standalone View
Standalone View
source/blender/gpu/intern/gpu_material.c
| Show First 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | |||||
| struct GPUMaterial { | struct GPUMaterial { | ||||
| Scene *scene; /* DEPRECATED was only useful for lights. */ | Scene *scene; /* DEPRECATED was only useful for lights. */ | ||||
| Material *ma; | Material *ma; | ||||
| eGPUMaterialStatus status; | eGPUMaterialStatus status; | ||||
| const void *engine_type; /* attached engine type */ | const void *engine_type; /* attached engine type */ | ||||
| int options; /* to identify shader variations (shadow, probe, world background...) */ | int options; /* to identify shader variations (shadow, probe, world background...) */ | ||||
| bool is_volume_shader; /* is volumetric shader */ | |||||
| /* Nodes */ | /* Nodes */ | ||||
| GPUNodeGraph graph; | GPUNodeGraph graph; | ||||
| /* for binding the material */ | /* for binding the material */ | ||||
| GPUPass *pass; | GPUPass *pass; | ||||
| /* XXX: Should be in Material. But it depends on the output node | /* XXX: Should be in Material. But it depends on the output node | ||||
| * used and since the output selection is different for GPUMaterial... | * used and since the output selection is different for GPUMaterial... | ||||
| */ | */ | ||||
| int domain; | bool has_volume_output; | ||||
| bool has_surface_output; | |||||
| /* Only used by Eevee to know which bsdf are used. */ | /* Only used by Eevee to know which bsdf are used. */ | ||||
| int flag; | int flag; | ||||
| /* Used by 2.8 pipeline */ | /* Used by 2.8 pipeline */ | ||||
| GPUUniformBuffer *ubo; /* UBOs for shader uniforms. */ | GPUUniformBuffer *ubo; /* UBOs for shader uniforms. */ | ||||
| /* Eevee SSS */ | /* Eevee SSS */ | ||||
| Show All 12 Lines | struct GPUMaterial { | ||||
| GSet *used_libraries; | GSet *used_libraries; | ||||
| #ifndef NDEBUG | #ifndef NDEBUG | ||||
| char name[64]; | char name[64]; | ||||
| #endif | #endif | ||||
| }; | }; | ||||
| enum { | enum { | ||||
| GPU_DOMAIN_SURFACE = (1 << 0), | GPU_USE_SURFACE_OUTPUT = (1 << 0), | ||||
| GPU_DOMAIN_VOLUME = (1 << 1), | GPU_USE_VOLUME_OUTPUT = (1 << 1), | ||||
| }; | }; | ||||
| /* Functions */ | /* Functions */ | ||||
| /* Returns the address of the future pointer to coba_tex */ | /* Returns the address of the future pointer to coba_tex */ | ||||
| GPUTexture **gpu_material_ramp_texture_row_set(GPUMaterial *mat, | GPUTexture **gpu_material_ramp_texture_row_set(GPUMaterial *mat, | ||||
| int size, | int size, | ||||
| float *pixels, | float *pixels, | ||||
| ▲ Show 20 Lines • Show All 440 Lines • ▼ Show 20 Lines | ListBase GPU_material_attributes(GPUMaterial *material) | ||||
| return material->graph.attributes; | return material->graph.attributes; | ||||
| } | } | ||||
| ListBase GPU_material_textures(GPUMaterial *material) | ListBase GPU_material_textures(GPUMaterial *material) | ||||
| { | { | ||||
| return material->graph.textures; | return material->graph.textures; | ||||
| } | } | ||||
| ListBase GPU_material_volume_grids(GPUMaterial *material) | |||||
| { | |||||
| return material->graph.volume_grids; | |||||
| } | |||||
| void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link) | void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link) | ||||
| { | { | ||||
| if (!material->graph.outlink) { | if (!material->graph.outlink) { | ||||
| material->graph.outlink = link; | material->graph.outlink = link; | ||||
| } | } | ||||
| } | } | ||||
| GPUNodeGraph *gpu_material_node_graph(GPUMaterial *material) | GPUNodeGraph *gpu_material_node_graph(GPUMaterial *material) | ||||
| Show All 9 Lines | |||||
| /* Return true if the material compilation has not yet begin or begin. */ | /* Return true if the material compilation has not yet begin or begin. */ | ||||
| eGPUMaterialStatus GPU_material_status(GPUMaterial *mat) | eGPUMaterialStatus GPU_material_status(GPUMaterial *mat) | ||||
| { | { | ||||
| return mat->status; | return mat->status; | ||||
| } | } | ||||
| /* Code generation */ | /* Code generation */ | ||||
| bool GPU_material_use_domain_surface(GPUMaterial *mat) | bool GPU_material_has_surface_output(GPUMaterial *mat) | ||||
| { | |||||
| return mat->has_surface_output; | |||||
| } | |||||
| bool GPU_material_has_volume_output(GPUMaterial *mat) | |||||
| { | { | ||||
| return (mat->domain & GPU_DOMAIN_SURFACE); | return mat->has_volume_output; | ||||
| } | } | ||||
| bool GPU_material_use_domain_volume(GPUMaterial *mat) | bool GPU_material_is_volume_shader(GPUMaterial *mat) | ||||
| { | { | ||||
| return (mat->domain & GPU_DOMAIN_VOLUME); | return mat->is_volume_shader; | ||||
| } | } | ||||
| void GPU_material_flag_set(GPUMaterial *mat, eGPUMatFlag flag) | void GPU_material_flag_set(GPUMaterial *mat, eGPUMatFlag flag) | ||||
| { | { | ||||
| mat->flag |= flag; | mat->flag |= flag; | ||||
| } | } | ||||
| bool GPU_material_flag_get(GPUMaterial *mat, eGPUMatFlag flag) | bool GPU_material_flag_get(GPUMaterial *mat, eGPUMatFlag flag) | ||||
| Show All 20 Lines | |||||
| * This is enforced since constructing other arguments to this function may be expensive | * This is enforced since constructing other arguments to this function may be expensive | ||||
| * so only do this when they are needed. | * so only do this when they are needed. | ||||
| */ | */ | ||||
| GPUMaterial *GPU_material_from_nodetree(Scene *scene, | GPUMaterial *GPU_material_from_nodetree(Scene *scene, | ||||
| struct Material *ma, | struct Material *ma, | ||||
| struct bNodeTree *ntree, | struct bNodeTree *ntree, | ||||
| ListBase *gpumaterials, | ListBase *gpumaterials, | ||||
| const void *engine_type, | const void *engine_type, | ||||
| int options, | const int options, | ||||
| const bool is_volume_shader, | |||||
| const char *vert_code, | const char *vert_code, | ||||
| const char *geom_code, | const char *geom_code, | ||||
| const char *frag_lib, | const char *frag_lib, | ||||
| const char *defines, | const char *defines, | ||||
| const char *name) | const char *name) | ||||
| { | { | ||||
| LinkData *link; | LinkData *link; | ||||
| bool has_volume_output, has_surface_output; | bool has_volume_output, has_surface_output; | ||||
| /* Caller must re-use materials. */ | /* Caller must re-use materials. */ | ||||
| BLI_assert(GPU_material_from_nodetree_find(gpumaterials, engine_type, options) == NULL); | BLI_assert(GPU_material_from_nodetree_find(gpumaterials, engine_type, options) == NULL); | ||||
| /* allocate material */ | /* allocate material */ | ||||
| GPUMaterial *mat = MEM_callocN(sizeof(GPUMaterial), "GPUMaterial"); | GPUMaterial *mat = MEM_callocN(sizeof(GPUMaterial), "GPUMaterial"); | ||||
| mat->ma = ma; | mat->ma = ma; | ||||
| mat->scene = scene; | mat->scene = scene; | ||||
| mat->engine_type = engine_type; | mat->engine_type = engine_type; | ||||
| mat->options = options; | mat->options = options; | ||||
| mat->is_volume_shader = is_volume_shader; | |||||
fclem: i believe this has to also be persent in some way inside the `options` in order to fetch the… | |||||
Done Inline ActionsEevee already sets distinct options for surfaces and volumes, but these option flags are defined in the Eevee code and not accessible outside of it. GPU_material_from_nodetree_find works the same as before. What it does is make this information available to shader nodes so they know if compilation is being done for a surface or volume shader. brecht: Eevee already sets distinct options for surfaces and volumes, but these option flags are… | |||||
| #ifndef NDEBUG | #ifndef NDEBUG | ||||
| BLI_snprintf(mat->name, sizeof(mat->name), "%s", name); | BLI_snprintf(mat->name, sizeof(mat->name), "%s", name); | ||||
| #else | #else | ||||
| UNUSED_VARS(name); | UNUSED_VARS(name); | ||||
| #endif | #endif | ||||
| mat->used_libraries = BLI_gset_new( | mat->used_libraries = BLI_gset_new( | ||||
| BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "GPUMaterial.used_libraries"); | BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "GPUMaterial.used_libraries"); | ||||
| /* localize tree to create links for reroute and mute */ | /* localize tree to create links for reroute and mute */ | ||||
| bNodeTree *localtree = ntreeLocalize(ntree); | bNodeTree *localtree = ntreeLocalize(ntree); | ||||
| ntreeGPUMaterialNodes(localtree, mat, &has_surface_output, &has_volume_output); | ntreeGPUMaterialNodes(localtree, mat, &has_surface_output, &has_volume_output); | ||||
| gpu_material_ramp_texture_build(mat); | gpu_material_ramp_texture_build(mat); | ||||
| SET_FLAG_FROM_TEST(mat->domain, has_surface_output, GPU_DOMAIN_SURFACE); | mat->has_surface_output = has_surface_output; | ||||
| SET_FLAG_FROM_TEST(mat->domain, has_volume_output, GPU_DOMAIN_VOLUME); | mat->has_volume_output = has_volume_output; | ||||
| if (mat->graph.outlink) { | if (mat->graph.outlink) { | ||||
| /* HACK: this is only for eevee. We add the define here after the nodetree evaluation. */ | /* HACK: this is only for eevee. We add the define here after the nodetree evaluation. */ | ||||
| if (GPU_material_flag_get(mat, GPU_MATFLAG_SSS)) { | if (GPU_material_flag_get(mat, GPU_MATFLAG_SSS)) { | ||||
| defines = BLI_string_joinN(defines, | defines = BLI_string_joinN(defines, | ||||
| "#ifndef USE_ALPHA_BLEND\n" | "#ifndef USE_ALPHA_BLEND\n" | ||||
| "# define USE_SSS\n" | "# define USE_SSS\n" | ||||
| "#endif\n"); | "#endif\n"); | ||||
| ▲ Show 20 Lines • Show All 91 Lines • Show Last 20 Lines | |||||
i believe this has to also be persent in some way inside the options in order to fetch the right shader in GPU_material_from_nodetree_find.
It is not obvious to me this is the currently the case.