Blender V4.3
gpu_material.cc File Reference
#include <algorithm>
#include <cmath>
#include <cstring>
#include "MEM_guardedalloc.h"
#include "DNA_material_types.h"
#include "DNA_scene_types.h"
#include "DNA_world_types.h"
#include "BLI_listbase.h"
#include "BLI_math_vector.h"
#include "BLI_string.h"
#include "BLI_time.h"
#include "BLI_utildefines.h"
#include "BKE_main.hh"
#include "BKE_material.h"
#include "BKE_node.hh"
#include "NOD_shader.h"
#include "GPU_material.hh"
#include "GPU_shader.hh"
#include "GPU_texture.hh"
#include "GPU_uniform_buffer.hh"
#include "DRW_engine.hh"
#include "gpu_codegen.hh"
#include "gpu_node_graph.hh"
#include "atomic_ops.h"

Go to the source code of this file.

Classes

struct  GPUColorBandBuilder
 
struct  GPUSkyBuilder
 
struct  GPUMaterial
 
struct  GPUSssKernelData
 

Macros

#define MAX_COLOR_BAND   128
 
#define MAX_GPU_SKIES   8
 
#define ASYNC_OPTIMIZED_PASS_CREATION   0
 
#define SSS_SAMPLES   65
 
#define SSS_EXPONENT   2.0f /* Importance sampling exponent */
 

Functions

GPUTexture ** gpu_material_sky_texture_layer_set (GPUMaterial *mat, int width, int height, const float *pixels, float *row)
 
GPUTexture ** gpu_material_ramp_texture_row_set (GPUMaterial *mat, int size, const float *pixels, float *r_row)
 
static void gpu_material_ramp_texture_build (GPUMaterial *mat)
 
static void gpu_material_sky_texture_build (GPUMaterial *mat)
 
void GPU_material_free_single (GPUMaterial *material)
 
void GPU_material_free (ListBase *gpumaterial)
 
SceneGPU_material_scene (GPUMaterial *material)
 
GPUPassGPU_material_get_pass (GPUMaterial *material)
 
GPUShaderGPU_material_get_shader (GPUMaterial *material)
 
GPUShaderGPU_material_get_shader_base (GPUMaterial *material)
 
const char * GPU_material_get_name (GPUMaterial *material)
 
MaterialGPU_material_get_material (GPUMaterial *material)
 
GPUUniformBuf * GPU_material_uniform_buffer_get (GPUMaterial *material)
 
void GPU_material_uniform_buffer_create (GPUMaterial *material, ListBase *inputs)
 
ListBase GPU_material_attributes (const GPUMaterial *material)
 
ListBase GPU_material_textures (GPUMaterial *material)
 
const GPUUniformAttrListGPU_material_uniform_attributes (const GPUMaterial *material)
 
const ListBaseGPU_material_layer_attributes (const GPUMaterial *material)
 
bool GPU_material_sss_profile_create (GPUMaterial *material, float radii[3])
 
void GPU_material_output_surface (GPUMaterial *material, GPUNodeLink *link)
 
void GPU_material_output_volume (GPUMaterial *material, GPUNodeLink *link)
 
void GPU_material_output_displacement (GPUMaterial *material, GPUNodeLink *link)
 
void GPU_material_output_thickness (GPUMaterial *material, GPUNodeLink *link)
 
void GPU_material_add_output_link_aov (GPUMaterial *material, GPUNodeLink *link, int hash)
 
void GPU_material_add_output_link_composite (GPUMaterial *material, GPUNodeLink *link)
 
char * GPU_material_split_sub_function (GPUMaterial *material, eGPUType return_type, GPUNodeLink **link)
 
GPUNodeGraphgpu_material_node_graph (GPUMaterial *material)
 
eGPUMaterialStatus GPU_material_status (GPUMaterial *mat)
 
void GPU_material_status_set (GPUMaterial *mat, eGPUMaterialStatus status)
 
eGPUMaterialOptimizationStatus GPU_material_optimization_status (GPUMaterial *mat)
 
void GPU_material_optimization_status_set (GPUMaterial *mat, eGPUMaterialOptimizationStatus status)
 
bool GPU_material_optimization_ready (GPUMaterial *mat)
 
void GPU_material_set_default (GPUMaterial *material, GPUMaterial *default_material)
 
bool GPU_material_has_surface_output (GPUMaterial *mat)
 
bool GPU_material_has_volume_output (GPUMaterial *mat)
 
bool GPU_material_has_displacement_output (GPUMaterial *mat)
 
void GPU_material_flag_set (GPUMaterial *mat, eGPUMaterialFlag flag)
 
bool GPU_material_flag_get (const GPUMaterial *mat, eGPUMaterialFlag flag)
 
eGPUMaterialFlag GPU_material_flag (const GPUMaterial *mat)
 
bool GPU_material_recalc_flag_get (GPUMaterial *mat)
 
uint64_t GPU_material_uuid_get (GPUMaterial *mat)
 
GPUMaterialGPU_material_from_nodetree (Scene *scene, Material *ma, bNodeTree *ntree, ListBase *gpumaterials, const char *name, eGPUMaterialEngine engine, uint64_t shader_uuid, bool is_volume_shader, bool is_lookdev, GPUCodegenCallbackFn callback, void *thunk, GPUMaterialPassReplacementCallbackFn pass_replacement_cb)
 
void GPU_material_acquire (GPUMaterial *mat)
 
void GPU_material_release (GPUMaterial *mat)
 
static void gpu_material_finalize (GPUMaterial *mat, bool success)
 
void GPU_material_compile (GPUMaterial *mat)
 
void GPU_material_async_compile (GPUMaterial *mat)
 
bool GPU_material_async_try_finalize (GPUMaterial *mat)
 
void GPU_material_optimize (GPUMaterial *mat)
 
void GPU_materials_free (Main *bmain)
 
GPUMaterialGPU_material_from_callbacks (eGPUMaterialEngine engine, ConstructGPUMaterialFn construct_function_cb, GPUCodegenCallbackFn generate_code_function_cb, void *thunk)
 

Detailed Description

Manages materials, lights and textures.

Definition in file gpu_material.cc.

Macro Definition Documentation

◆ ASYNC_OPTIMIZED_PASS_CREATION

#define ASYNC_OPTIMIZED_PASS_CREATION   0

Whether the optimized variant of the GPUPass should be created asynchronously. Usage of this depends on whether there are possible threading challenges of doing so. Currently, the overhead of GPU_generate_pass is relatively small in comparison to shader compilation, though this option exists in case any potential scenarios for material graph optimization cause a slow down on the main thread.

NOTE: The actual shader program for the optimized pass will always be compiled asynchronously, this flag controls whether shader node graph source serialization happens on the compilation worker thread as well.

Definition at line 59 of file gpu_material.cc.

◆ MAX_COLOR_BAND

#define MAX_COLOR_BAND   128

Definition at line 46 of file gpu_material.cc.

Referenced by gpu_material_ramp_texture_row_set().

◆ MAX_GPU_SKIES

#define MAX_GPU_SKIES   8

Definition at line 47 of file gpu_material.cc.

Referenced by gpu_material_sky_texture_layer_set().

◆ SSS_EXPONENT

#define SSS_EXPONENT   2.0f /* Importance sampling exponent */

Definition at line 380 of file gpu_material.cc.

◆ SSS_SAMPLES

#define SSS_SAMPLES   65

Definition at line 379 of file gpu_material.cc.

Function Documentation

◆ GPU_material_acquire()

void GPU_material_acquire ( GPUMaterial * mat)

◆ GPU_material_add_output_link_aov()

void GPU_material_add_output_link_aov ( GPUMaterial * material,
GPUNodeLink * link,
int hash )

◆ GPU_material_add_output_link_composite()

void GPU_material_add_output_link_composite ( GPUMaterial * material,
GPUNodeLink * link )

Definition at line 452 of file gpu_material.cc.

References BLI_addtail(), MEM_callocN, and GPUNodeGraphOutputLink::outlink.

◆ GPU_material_async_compile()

◆ GPU_material_async_try_finalize()

bool GPU_material_async_try_finalize ( GPUMaterial * mat)

◆ GPU_material_attributes()

◆ GPU_material_compile()

◆ gpu_material_finalize()

static void gpu_material_finalize ( GPUMaterial * mat,
bool success )
static

Perform asynchronous Render Pipeline State Object (PSO) compilation.

Warm PSO cache within asynchronous compilation thread using default material as source. GPU_shader_warm_cache(..) performs the API-specific PSO compilation using the assigned parent shader's cached PSO descriptors as an input.

This is only applied if the given material has a specified default reference material available, and the default material is already compiled.

As PSOs do not always match for default shaders, we limit warming for PSO configurations to ensure compile time remains fast, as these first entries will be the most commonly used PSOs. As not all PSOs are necessarily required immediately, this limit should remain low (1-3 at most).

Definition at line 721 of file gpu_material.cc.

References GPUMaterial::default_mat, ELEM, GPUMaterial::flag, GPU_MAT_FAILED, GPU_MAT_OPTIMIZATION_SKIP, GPU_MAT_SUCCESS, GPU_MATFLAG_UPDATED, gpu_node_graph_free(), gpu_node_graph_free_nodes(), GPU_pass_release(), GPU_pass_shader_get(), GPU_shader_set_parent(), GPU_shader_warm_cache(), GPUMaterial::graph, GPUMaterial::optimization_status, GPUMaterial::pass, and GPUMaterial::status.

Referenced by GPU_material_async_try_finalize(), and GPU_material_compile().

◆ GPU_material_flag()

eGPUMaterialFlag GPU_material_flag ( const GPUMaterial * mat)

Definition at line 569 of file gpu_material.cc.

References GPUMaterial::flag.

Referenced by GPUCodegen::GPUCodegen().

◆ GPU_material_flag_get()

◆ GPU_material_flag_set()

void GPU_material_flag_set ( GPUMaterial * mat,
eGPUMaterialFlag flag )

Definition at line 555 of file gpu_material.cc.

References flag, GPUMaterial::flag, GPU_MATFLAG_COAT, and GPU_MATFLAG_GLOSSY.

Referenced by GPU_attribute(), blender::nodes::node_shader_normal_map_cc::gpu_shader_normal_map(), blender::nodes::node_shader_particle_info_cc::gpu_shader_particle_info(), blender::nodes::node_shader_ambient_occlusion_cc::node_shader_gpu_ambient_occlusion(), blender::nodes::node_shader_bsdf_diffuse_cc::node_shader_gpu_bsdf_diffuse(), blender::nodes::node_shader_bsdf_glass_cc::node_shader_gpu_bsdf_glass(), blender::nodes::node_shader_bsdf_glossy_cc::node_shader_gpu_bsdf_glossy(), blender::nodes::node_shader_bsdf_hair_cc::node_shader_gpu_bsdf_hair(), blender::nodes::node_shader_bsdf_metallic_cc::node_shader_gpu_bsdf_metallic(), blender::nodes::node_shader_bsdf_principled_cc::node_shader_gpu_bsdf_principled(), blender::nodes::node_shader_bsdf_ray_portal_cc::node_shader_gpu_bsdf_ray_portal(), blender::nodes::node_shader_bsdf_refraction_cc::node_shader_gpu_bsdf_refraction(), blender::nodes::node_shader_bsdf_sheen_cc::node_shader_gpu_bsdf_sheen(), blender::nodes::node_shader_bsdf_toon_cc::node_shader_gpu_bsdf_toon(), blender::nodes::node_shader_bsdf_translucent_cc::node_shader_gpu_bsdf_translucent(), blender::nodes::node_shader_bsdf_transparent_cc::node_shader_gpu_bsdf_transparent(), blender::nodes::node_shader_eevee_specular_cc::node_shader_gpu_eevee_specular(), blender::nodes::node_shader_emission_cc::node_shader_gpu_emission(), blender::nodes::node_shader_geometry_cc::node_shader_gpu_geometry(), blender::nodes::node_shader_bsdf_hair_principled_cc::node_shader_gpu_hair_principled(), blender::nodes::node_shader_object_info_cc::node_shader_gpu_object_info(), blender::nodes::node_shader_output_aov_cc::node_shader_gpu_output_aov(), blender::nodes::node_shader_shader_to_rgb_cc::node_shader_gpu_shadertorgb(), blender::nodes::node_shader_subsurface_scattering_cc::node_shader_gpu_subsurface_scattering(), blender::nodes::node_shader_volume_absorption_cc::node_shader_gpu_volume_absorption(), blender::nodes::node_shader_volume_principled_cc::node_shader_gpu_volume_principled(), blender::nodes::node_shader_volume_scatter_cc::node_shader_gpu_volume_scatter(), and blender::nodes::node_shader_wireframe_cc::node_shader_gpu_wireframe().

◆ GPU_material_free()

◆ GPU_material_free_single()

◆ GPU_material_from_callbacks()

◆ GPU_material_from_nodetree()

GPUMaterial * GPU_material_from_nodetree ( Scene * scene,
Material * ma,
bNodeTree * ntree,
ListBase * gpumaterials,
const char * name,
eGPUMaterialEngine engine,
uint64_t shader_uuid,
bool is_volume_shader,
bool is_lookdev,
GPUCodegenCallbackFn callback,
void * thunk,
GPUMaterialPassReplacementCallbackFn pass_replacement_cb )

WORKAROUND: The node tree code is never executed in default replaced passes, but the GPU validation will still complain if the node tree UBO is not bound. So we create a dummy UBO with (at least) the size of the default material one (192 bytes). We allocate 256 bytes to leave some room for future changes.

Definition at line 588 of file gpu_material.cc.

References BLI_addtail(), BLI_assert, BLI_ghashutil_ptrcmp(), BLI_ghashutil_ptrhash(), BLI_gset_new(), callback, LinkData::data, GPUMaterial::default_mat, GPUMaterial::engine, GPUMaterial::flag, GPU_generate_pass(), GPU_MAT_CREATED, GPU_MAT_FAILED, GPU_MAT_OPTIMIZATION_READY, GPU_MAT_OPTIMIZATION_SKIP, GPU_MAT_OPTIMIZATION_SUCCESS, GPU_MAT_SUCCESS, GPU_material_optimization_status_set(), gpu_material_ramp_texture_build(), gpu_material_sky_texture_build(), GPU_MATFLAG_LOOKDEV_HACK, GPU_MATFLAG_UPDATED, gpu_node_graph_free(), gpu_node_graph_free_nodes(), GPU_pass_acquire(), GPU_pass_shader_get(), GPU_pass_should_optimize(), GPU_uniformbuf_create_ex(), GPUMaterial::graph, bNodeTree::id, GPUMaterial::is_volume_shader, LISTBASE_FOREACH, GPUMaterial::ma, MEM_callocN, MEM_freeN(), GPUMaterial::name, blender::bke::node_tree_free_local_tree(), blender::bke::node_tree_localize(), ntreeGPUMaterialNodes, GPUMaterial::optimization_status, GPUMaterial::optimized_pass, GPUMaterial::pass, ID::py_instance, GPUMaterial::refcount, GPUMaterial::scene, scene, GPUMaterial::status, STRNCPY, GPUMaterial::ubo, GPUNodeGraph::used_libraries, and GPUMaterial::uuid.

Referenced by DRW_shader_from_material(), DRW_shader_from_world(), and blender::eevee::ShaderModule::material_shader_get().

◆ GPU_material_get_material()

◆ GPU_material_get_name()

◆ GPU_material_get_pass()

◆ GPU_material_get_shader()

GPUShader * GPU_material_get_shader ( GPUMaterial * material)

Return the most optimal shader configuration for the given material.

Definition at line 316 of file gpu_material.cc.

References GPU_MAT_OPTIMIZATION_SUCCESS, GPU_material_optimization_status(), and GPU_pass_shader_get().

Referenced by blender::realtime_compositor::ShaderOperation::execute(), and blender::eevee::ShaderKey::ShaderKey().

◆ GPU_material_get_shader_base()

GPUShader * GPU_material_get_shader_base ( GPUMaterial * material)

Return the base un-optimized shader.

Definition at line 328 of file gpu_material.cc.

References GPU_pass_shader_get().

◆ GPU_material_has_displacement_output()

◆ GPU_material_has_surface_output()

bool GPU_material_has_surface_output ( GPUMaterial * mat)

Definition at line 540 of file gpu_material.cc.

References GPUMaterial::has_surface_output.

◆ GPU_material_has_volume_output()

◆ GPU_material_layer_attributes()

const ListBase * GPU_material_layer_attributes ( const GPUMaterial * material)

◆ gpu_material_node_graph()

◆ GPU_material_optimization_ready()

bool GPU_material_optimization_ready ( GPUMaterial * mat)

◆ GPU_material_optimization_status()

eGPUMaterialOptimizationStatus GPU_material_optimization_status ( GPUMaterial * mat)

Return status for asynchronous optimization jobs.

Definition at line 504 of file gpu_material.cc.

References GPUMaterial::optimization_status.

Referenced by drw_deferred_queue_append(), DRW_shader_queue_optimize_material(), GPU_material_get_pass(), and GPU_material_get_shader().

◆ GPU_material_optimization_status_set()

◆ GPU_material_optimize()

void GPU_material_optimize ( GPUMaterial * mat)

Material Optimization.

Note
Compiles optimal version of shader graph, populating mat->optimized_pass. This operation should always be deferred until existing compilations have completed. Default un-optimized materials will still exist for interactive material editing performance.

Perform asynchronous Render Pipeline State Object (PSO) compilation.

Warm PSO cache within asynchronous compilation thread for optimized materials. This setup assigns the original unoptimized shader as a "parent" shader for the optimized version. This then allows the associated GPU backend to compile PSOs within this asynchronous pass, using the identical PSO descriptors of the parent shader.

This eliminates all run-time stuttering associated with material optimization and ensures realtime material editing and animation remains seamless, while retaining optimal realtime performance.

Definition at line 813 of file gpu_material.cc.

References BLI_assert, ELEM, GPUMaterial::engine, GPU_generate_pass(), GPU_MAT_OPTIMIZATION_READY, GPU_MAT_OPTIMIZATION_SKIP, GPU_MAT_OPTIMIZATION_SUCCESS, GPU_MAT_SUCCESS, GPU_material_optimization_status_set(), gpu_node_graph_free_nodes(), GPU_pass_compile(), GPU_pass_release(), GPU_pass_shader_get(), GPU_shader_set_parent(), GPU_shader_warm_cache(), GPUMaterial::graph, GPUMaterial::name, GPUMaterial::optimization_status, GPUMaterial::optimized_pass, GPUMaterial::pass, and GPUMaterial::status.

Referenced by drw_deferred_shader_compilation_exec().

◆ GPU_material_output_displacement()

void GPU_material_output_displacement ( GPUMaterial * material,
GPUNodeLink * link )

◆ GPU_material_output_surface()

◆ GPU_material_output_thickness()

void GPU_material_output_thickness ( GPUMaterial * material,
GPUNodeLink * link )

◆ GPU_material_output_volume()

◆ gpu_material_ramp_texture_build()

◆ gpu_material_ramp_texture_row_set()

GPUTexture ** gpu_material_ramp_texture_row_set ( GPUMaterial * mat,
int size,
const float * pixels,
float * r_row )

◆ GPU_material_recalc_flag_get()

bool GPU_material_recalc_flag_get ( GPUMaterial * mat)

Definition at line 574 of file gpu_material.cc.

References GPUMaterial::flag, and GPU_MATFLAG_UPDATED.

◆ GPU_material_release()

void GPU_material_release ( GPUMaterial * mat)

Definition at line 716 of file gpu_material.cc.

References GPU_material_free_single().

Referenced by drw_deferred_shader_compilation_exec().

◆ GPU_material_scene()

Scene * GPU_material_scene ( GPUMaterial * material)

Definition at line 301 of file gpu_material.cc.

◆ GPU_material_set_default()

void GPU_material_set_default ( GPUMaterial * material,
GPUMaterial * default_material )

Store reference to a similar default material for asynchronous PSO cache warming.

This function expects material to have not yet been compiled and for default_material to be ready. When compiling material as part of an asynchronous shader compilation job, use existing PSO descriptors from default_material's shader to also compile PSOs for this new material asynchronously, rather than at runtime.

The default_material options should match this new materials options in order for PSO descriptors to match those needed by the new material.

NOTE: default_material must exist when GPU_material_compile(..) is called for material.

See GPU_shader_warm_cache(..) for more information.

Definition at line 531 of file gpu_material.cc.

◆ gpu_material_sky_texture_build()

◆ gpu_material_sky_texture_layer_set()

GPUTexture ** gpu_material_sky_texture_layer_set ( GPUMaterial * mat,
int width,
int height,
const float * pixels,
float * row )

◆ GPU_material_split_sub_function()

char * GPU_material_split_sub_function ( GPUMaterial * material,
eGPUType return_type,
GPUNodeLink ** link )

Wrap a part of the material graph into a function. You need then need to call the function by using something like GPU_differentiate_float_function.

Note
This replace the link by a constant to break the link with the main graph.
Parameters
return_typesub function return type. Output is cast to this type.
linklink to use as the sub function output.
Returns
the name of the generated function.

Definition at line 460 of file gpu_material.cc.

References BLI_addtail(), BLI_assert, GPU_FLOAT, GPU_link(), GPU_VEC3, GPU_VEC4, MEM_callocN, GPUNodeGraphFunctionLink::name, GPUNodeGraphFunctionLink::outlink, and SNPRINTF.

Referenced by blender::nodes::node_shader_bump_cc::gpu_shader_bump().

◆ GPU_material_sss_profile_create()

◆ GPU_material_status()

eGPUMaterialStatus GPU_material_status ( GPUMaterial * mat)

Return true if the material compilation has not yet begin or begin.

Definition at line 494 of file gpu_material.cc.

References GPUMaterial::status.

Referenced by drw_deferred_shader_add(), DRW_shader_queue_optimize_material(), and blender::eevee::WorldVolumePipeline::sync().

◆ GPU_material_status_set()

◆ GPU_material_textures()

◆ GPU_material_uniform_attributes()

◆ GPU_material_uniform_buffer_create()

void GPU_material_uniform_buffer_create ( GPUMaterial * material,
ListBase * inputs )

Create dynamic UBO from parameters

Parameters
inputsItems are LinkData, data is GPUInput (BLI_genericNodeN(GPUInput)).

Definition at line 348 of file gpu_material.cc.

References GPU_uniformbuf_create_from_list().

Referenced by GPUCodegen::generate_uniform_buffer().

◆ GPU_material_uniform_buffer_get()

GPUUniformBuf * GPU_material_uniform_buffer_get ( GPUMaterial * material)

◆ GPU_material_uuid_get()

◆ GPU_materials_free()