Blender V4.3
gpu_material.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2006 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
11#include <algorithm>
12#include <cmath>
13#include <cstring>
14
15#include "MEM_guardedalloc.h"
16
17#include "DNA_material_types.h"
18#include "DNA_scene_types.h"
19#include "DNA_world_types.h"
20
21#include "BLI_listbase.h"
22#include "BLI_math_vector.h"
23#include "BLI_string.h"
24#include "BLI_time.h"
25#include "BLI_utildefines.h"
26
27#include "BKE_main.hh"
28#include "BKE_material.h"
29#include "BKE_node.hh"
30
31#include "NOD_shader.h"
32
33#include "GPU_material.hh"
34#include "GPU_shader.hh"
35#include "GPU_texture.hh"
36#include "GPU_uniform_buffer.hh"
37
38#include "DRW_engine.hh"
39
40#include "gpu_codegen.hh"
41#include "gpu_node_graph.hh"
42
43#include "atomic_ops.h"
44
45/* Structs */
46#define MAX_COLOR_BAND 128
47#define MAX_GPU_SKIES 8
48
59#define ASYNC_OPTIMIZED_PASS_CREATION 0
60
62 float pixels[MAX_COLOR_BAND][CM_TABLE + 1][4];
64};
65
70
72 /* Contains #GPUShader and source code for deferred compilation.
73 * Can be shared between similar material (i.e: sharing same node-tree topology). */
75 /* Optimized GPUPass, situationally compiled after initial pass for optimal realtime performance.
76 * This shader variant bakes dynamic uniform data as constant. This variant will not use
77 * the ubo, and instead bake constants directly into the shader source. */
79 /* Optimization status.
80 * We also use this status to determine whether this material should be considered for
81 * optimization. Only sufficiently complex shaders benefit from constant-folding optimizations.
82 * `GPU_MAT_OPTIMIZATION_READY` -> shader should be optimized and is ready for optimization.
83 * `GPU_MAT_OPTIMIZATION_SKIP` -> Shader should not be optimized as it would not benefit
84 * performance to do so, based on the heuristic.
85 */
88#if ASYNC_OPTIMIZED_PASS_CREATION == 1
89 struct DeferredOptimizePass {
91 void *thunk;
92 } DeferredOptimizePass;
93 struct DeferredOptimizePass optimize_pass_info;
94#endif
95
97 GPUUniformBuf *ubo;
104 /* Identify shader variations (shadow, probe, world background...) */
106 /* Number of generated function. */
110
116 GPUTexture *coba_tex;
120 GPUTexture *sky_tex;
123 /* Low level node graph(s). Also contains resources needed by the material. */
125
131
137 GPUUniformBuf *sss_profile; /* UBO containing SSS profile. */
138 GPUTexture *sss_tex_profile; /* Texture containing SSS profile. */
140 float sss_radii[3];
141
143
145
146#ifndef NDEBUG
147 char name[64];
148#else
149 char name[16];
150#endif
151};
152
153/* Functions */
154
156 GPUMaterial *mat, int width, int height, const float *pixels, float *row)
157{
158 /* In order to put all sky textures into one 2D array texture,
159 * we need them to be the same size. */
160 BLI_assert(width == GPU_SKY_WIDTH);
161 BLI_assert(height == GPU_SKY_HEIGHT);
162 UNUSED_VARS_NDEBUG(width, height);
163
164 if (mat->sky_builder == nullptr) {
165 mat->sky_builder = static_cast<GPUSkyBuilder *>(
166 MEM_mallocN(sizeof(GPUSkyBuilder), "GPUSkyBuilder"));
167 mat->sky_builder->current_layer = 0;
168 }
169
170 int layer = mat->sky_builder->current_layer;
171 *row = float(layer);
172
173 if (*row == MAX_GPU_SKIES) {
174 printf("Too many sky textures in shader!\n");
175 }
176 else {
177 float *dst = (float *)mat->sky_builder->pixels[layer];
178 memcpy(dst, pixels, sizeof(float) * GPU_SKY_WIDTH * GPU_SKY_HEIGHT * 4);
179 mat->sky_builder->current_layer += 1;
180 }
181
182 return &mat->sky_tex;
183}
184
186 int size,
187 const float *pixels,
188 float *r_row)
189{
190 /* In order to put all the color-bands into one 1D array texture,
191 * we need them to be the same size. */
192 BLI_assert(size == CM_TABLE + 1);
193 UNUSED_VARS_NDEBUG(size);
194
195 if (mat->coba_builder == nullptr) {
196 mat->coba_builder = static_cast<GPUColorBandBuilder *>(
197 MEM_mallocN(sizeof(GPUColorBandBuilder), "GPUColorBandBuilder"));
198 mat->coba_builder->current_layer = 0;
199 }
200
201 int layer = mat->coba_builder->current_layer;
202 *r_row = float(layer);
203
204 if (*r_row == MAX_COLOR_BAND) {
205 printf("Too many color band in shader! Remove some Curve, Black Body or Color Ramp Node.\n");
206 }
207 else {
208 float *dst = (float *)mat->coba_builder->pixels[layer];
209 memcpy(dst, pixels, sizeof(float) * (CM_TABLE + 1) * 4);
210 mat->coba_builder->current_layer += 1;
211 }
212
213 return &mat->coba_tex;
214}
215
217{
218 if (mat->coba_builder == nullptr) {
219 return;
220 }
221
222 GPUColorBandBuilder *builder = mat->coba_builder;
223
224 mat->coba_tex = GPU_texture_create_1d_array("mat_ramp",
225 CM_TABLE + 1,
226 builder->current_layer,
227 1,
230 (float *)builder->pixels);
231
232 MEM_freeN(builder);
233 mat->coba_builder = nullptr;
234}
235
237{
238 if (mat->sky_builder == nullptr) {
239 return;
240 }
241
242 mat->sky_tex = GPU_texture_create_2d_array("mat_sky",
246 1,
249 (float *)mat->sky_builder->pixels);
250
252 mat->sky_builder = nullptr;
253}
254
256{
257 bool do_free = atomic_sub_and_fetch_uint32(&material->refcount, 1) == 0;
258 if (!do_free) {
259 return;
260 }
261
262 gpu_node_graph_free(&material->graph);
263
264 if (material->optimized_pass != nullptr) {
265 GPU_pass_release(material->optimized_pass);
266 }
267 if (material->pass != nullptr) {
268 GPU_pass_release(material->pass);
269 }
270 if (material->ubo != nullptr) {
271 GPU_uniformbuf_free(material->ubo);
272 }
273 if (material->coba_builder != nullptr) {
274 MEM_freeN(material->coba_builder);
275 }
276 if (material->coba_tex != nullptr) {
277 GPU_texture_free(material->coba_tex);
278 }
279 if (material->sky_tex != nullptr) {
280 GPU_texture_free(material->sky_tex);
281 }
282 if (material->sss_profile != nullptr) {
283 GPU_uniformbuf_free(material->sss_profile);
284 }
285 if (material->sss_tex_profile != nullptr) {
286 GPU_texture_free(material->sss_tex_profile);
287 }
288 MEM_freeN(material);
289}
290
291void GPU_material_free(ListBase *gpumaterial)
292{
293 LISTBASE_FOREACH (LinkData *, link, gpumaterial) {
294 GPUMaterial *material = static_cast<GPUMaterial *>(link->data);
296 GPU_material_free_single(material);
297 }
298 BLI_freelistN(gpumaterial);
299}
300
302{
303 return material->scene;
304}
305
307{
308 /* If an optimized pass variant is available, and optimization is
309 * flagged as complete, we use this one instead. */
311 material->optimized_pass) ?
312 material->optimized_pass :
313 material->pass;
314}
315
317{
318 /* If an optimized material shader variant is available, and optimization is
319 * flagged as complete, we use this one instead. */
320 GPUShader *shader = ((GPU_material_optimization_status(material) ==
322 material->optimized_pass) ?
323 GPU_pass_shader_get(material->optimized_pass) :
324 nullptr;
325 return (shader) ? shader : ((material->pass) ? GPU_pass_shader_get(material->pass) : nullptr);
326}
327
329{
330 return (material->pass) ? GPU_pass_shader_get(material->pass) : nullptr;
331}
332
333const char *GPU_material_get_name(GPUMaterial *material)
334{
335 return material->name;
336}
337
339{
340 return material->ma;
341}
342
344{
345 return material->ubo;
346}
347
349{
350 material->ubo = GPU_uniformbuf_create_from_list(inputs, material->name);
351}
352
354{
355 return material->graph.attributes;
356}
357
359{
360 return material->graph.textures;
361}
362
364{
365 const GPUUniformAttrList *attrs = &material->graph.uniform_attrs;
366 return attrs->count > 0 ? attrs : nullptr;
367}
368
370{
371 const ListBase *attrs = &material->graph.layer_attrs;
372 return !BLI_listbase_is_empty(attrs) ? attrs : nullptr;
373}
374
375#if 1 /* End of life code. */
376/* Eevee Subsurface scattering. */
377/* Based on Separable SSS. by Jorge Jimenez and Diego Gutierrez */
378
379# define SSS_SAMPLES 65
380# define SSS_EXPONENT 2.0f /* Importance sampling exponent */
381
384 float param[3], max_radius;
387 int pad[2];
388};
389
391
392bool GPU_material_sss_profile_create(GPUMaterial *material, float radii[3])
393{
394 /* Enable only once. */
395 if (material->sss_enabled) {
396 return false;
397 }
398 copy_v3_v3(material->sss_radii, radii);
399 material->sss_enabled = true;
400
401 /* Update / Create UBO */
402 if (material->sss_profile == nullptr) {
403 material->sss_profile = GPU_uniformbuf_create(sizeof(GPUSssKernelData));
404 }
405 return true;
406}
407
408# undef SSS_EXPONENT
409# undef SSS_SAMPLES
410#endif
411
413{
414 if (!material->graph.outlink_surface) {
415 material->graph.outlink_surface = link;
416 material->has_surface_output = true;
417 }
418}
419
421{
422 if (!material->graph.outlink_volume) {
423 material->graph.outlink_volume = link;
424 material->has_volume_output = true;
425 }
426}
427
429{
430 if (!material->graph.outlink_displacement) {
431 material->graph.outlink_displacement = link;
432 material->has_displacement_output = true;
433 }
434}
435
437{
438 if (!material->graph.outlink_thickness) {
439 material->graph.outlink_thickness = link;
440 }
441}
442
444{
445 GPUNodeGraphOutputLink *aov_link = static_cast<GPUNodeGraphOutputLink *>(
446 MEM_callocN(sizeof(GPUNodeGraphOutputLink), __func__));
447 aov_link->outlink = link;
448 aov_link->hash = hash;
449 BLI_addtail(&material->graph.outlink_aovs, aov_link);
450}
451
453{
454 GPUNodeGraphOutputLink *compositor_link = static_cast<GPUNodeGraphOutputLink *>(
455 MEM_callocN(sizeof(GPUNodeGraphOutputLink), __func__));
456 compositor_link->outlink = link;
457 BLI_addtail(&material->graph.outlink_compositor, compositor_link);
458}
459
461 eGPUType return_type,
462 GPUNodeLink **link)
463{
464 /* Force cast to return type. */
465 switch (return_type) {
466 case GPU_FLOAT:
467 GPU_link(material, "set_value", *link, link);
468 break;
469 case GPU_VEC3:
470 GPU_link(material, "set_rgb", *link, link);
471 break;
472 case GPU_VEC4:
473 GPU_link(material, "set_rgba", *link, link);
474 break;
475 default:
476 BLI_assert(0);
477 break;
478 }
479
480 GPUNodeGraphFunctionLink *func_link = static_cast<GPUNodeGraphFunctionLink *>(
481 MEM_callocN(sizeof(GPUNodeGraphFunctionLink), __func__));
482 func_link->outlink = *link;
483 SNPRINTF(func_link->name, "ntree_fn%d", material->generated_function_len++);
484 BLI_addtail(&material->graph.material_functions, func_link);
485
486 return func_link->name;
487}
488
490{
491 return &material->graph;
492}
493
498
500{
501 mat->status = status;
502}
503
508
510{
511 mat->optimization_status = status;
513 /* Reset creation timer to delay optimization pass. */
515 }
516}
517
519{
520 /* Timer threshold before optimizations will be queued.
521 * When materials are frequently being modified, optimization
522 * can incur CPU overhead from excessive compilation.
523 *
524 * As the optimization is entirely asynchronous, it is still beneficial
525 * to do this quickly to avoid build-up and improve runtime performance.
526 * The threshold just prevents compilations being queued frame after frame. */
527 const double optimization_time_threshold_s = 1.2;
528 return ((BLI_time_now_seconds() - mat->creation_time) >= optimization_time_threshold_s);
529}
530
531void GPU_material_set_default(GPUMaterial *material, GPUMaterial *default_material)
532{
533 if (material != default_material) {
534 material->default_mat = default_material;
535 }
536}
537
538/* Code generation */
539
544
549
554
556{
557 if ((flag & GPU_MATFLAG_GLOSSY) && (mat->flag & GPU_MATFLAG_GLOSSY)) {
558 /* Tag material using multiple glossy BSDF as using clear coat. */
559 mat->flag |= GPU_MATFLAG_COAT;
560 }
561 mat->flag |= flag;
562}
563
565{
566 return (mat->flag & flag) != 0;
567}
568
570{
571 return mat->flag;
572}
573
575{
576 /* NOTE: Consumes the flags. */
577
578 bool updated = (mat->flag & GPU_MATFLAG_UPDATED) != 0;
579 mat->flag &= ~GPU_MATFLAG_UPDATED;
580 return updated;
581}
582
584{
585 return mat->uuid;
586}
587
589 Material *ma,
590 bNodeTree *ntree,
591 ListBase *gpumaterials,
592 const char *name,
593 eGPUMaterialEngine engine,
594 uint64_t shader_uuid,
595 bool is_volume_shader,
596 bool is_lookdev,
598 void *thunk,
599 GPUMaterialPassReplacementCallbackFn pass_replacement_cb)
600{
601 /* Search if this material is not already compiled. */
602 LISTBASE_FOREACH (LinkData *, link, gpumaterials) {
603 GPUMaterial *mat = (GPUMaterial *)link->data;
604 if (mat->uuid == shader_uuid && mat->engine == engine) {
605 return mat;
606 }
607 }
608
609 GPUMaterial *mat = static_cast<GPUMaterial *>(MEM_callocN(sizeof(GPUMaterial), "GPUMaterial"));
610 mat->ma = ma;
611 mat->scene = scene;
612 mat->engine = engine;
613 mat->uuid = shader_uuid;
615 mat->status = GPU_MAT_CREATED;
616 mat->default_mat = nullptr;
617 mat->is_volume_shader = is_volume_shader;
619 BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "GPUNodeGraph.used_libraries");
620 mat->refcount = 1;
621 STRNCPY(mat->name, name);
622 if (is_lookdev) {
624 }
625
626 /* Localize tree to create links for reroute and mute. */
627 bNodeTree *localtree = blender::bke::node_tree_localize(ntree, nullptr);
628 ntreeGPUMaterialNodes(localtree, mat);
629
632
633 /* Use default material pass when possible. */
634 if (GPUPass *default_pass = pass_replacement_cb ? pass_replacement_cb(thunk, mat) : nullptr) {
635 mat->pass = default_pass;
642 mat->ubo = GPU_uniformbuf_create_ex(256, nullptr, "Dummy UBO");
643 }
644 else {
645 /* Create source code and search pass cache for an already compiled version. */
646 mat->pass = GPU_generate_pass(mat, &mat->graph, engine, callback, thunk, false);
647 }
648
649 if (mat->pass == nullptr) {
650 /* We had a cache hit and the shader has already failed to compile. */
651 mat->status = GPU_MAT_FAILED;
653 }
654 else {
655 /* Determine whether we should generate an optimized variant of the graph.
656 * Heuristic is based on complexity of default material pass and shader node graph. */
657 if (GPU_pass_should_optimize(mat->pass)) {
659 }
660
662 if (sh != nullptr) {
663 /* We had a cache hit and the shader is already compiled. */
664 mat->status = GPU_MAT_SUCCESS;
665
668 }
669 }
670
671 /* Generate optimized pass. */
673#if ASYNC_OPTIMIZED_PASS_CREATION == 1
674 mat->optimized_pass = nullptr;
675 mat->optimize_pass_info.callback = callback;
676 mat->optimize_pass_info.thunk = thunk;
677#else
678 mat->optimized_pass = GPU_generate_pass(mat, &mat->graph, engine, callback, thunk, true);
679 if (mat->optimized_pass == nullptr) {
680 /* Failed to create optimized pass. */
683 }
684 else {
685 GPUShader *optimized_sh = GPU_pass_shader_get(mat->optimized_pass);
686 if (optimized_sh != nullptr) {
687 /* Optimized shader already available. */
690 }
691 }
692#endif
693 }
694 }
695
696 /* Only free after GPU_pass_shader_get where GPUUniformBuf read data from the local tree. */
698 BLI_assert(!localtree->id.py_instance); /* Or call #BKE_libblock_free_data_py. */
699 MEM_freeN(localtree);
700
701 /* Note that even if building the shader fails in some way, we still keep
702 * it to avoid trying to compile again and again, and simply do not use
703 * the actual shader on drawing. */
704 LinkData *link = static_cast<LinkData *>(MEM_callocN(sizeof(LinkData), "GPUMaterialLink"));
705 link->data = mat;
706 BLI_addtail(gpumaterials, link);
707
708 return mat;
709}
710
715
720
721static void gpu_material_finalize(GPUMaterial *mat, bool success)
722{
724
725 if (success) {
727 if (sh != nullptr) {
728
742 if (!ELEM(mat->default_mat, nullptr, mat)) {
743 if (mat->default_mat->pass != nullptr) {
744 GPUShader *parent_sh = GPU_pass_shader_get(mat->default_mat->pass);
745 if (parent_sh) {
746 /* Skip warming if cached pass is identical to the default material. */
747 if (mat->default_mat->pass != mat->pass && parent_sh != sh) {
748 GPU_shader_set_parent(sh, parent_sh);
750 }
751 }
752 }
753 }
754
755 /* Flag success. */
756 mat->status = GPU_MAT_SUCCESS;
758 /* Only free node graph nodes if not required by secondary optimization pass. */
760 }
761 }
762 else {
763 mat->status = GPU_MAT_FAILED;
764 }
765 }
766 else {
767 mat->status = GPU_MAT_FAILED;
769 mat->pass = nullptr;
771 }
772}
773
775{
776 bool success;
778 BLI_assert(mat->pass);
779
780/* NOTE: The shader may have already been compiled here since we are
781 * sharing GPUShader across GPUMaterials. In this case it's a no-op. */
782#ifndef NDEBUG
783 success = GPU_pass_compile(mat->pass, mat->name);
784#else
785 success = GPU_pass_compile(mat->pass, __func__);
786#endif
787
788 gpu_material_finalize(mat, success);
789}
790
792{
794 BLI_assert(mat->pass);
795#ifndef NDEBUG
796 const char *name = mat->name;
797#else
798 const char *name = __func__;
799#endif
801}
802
804{
807 gpu_material_finalize(mat, GPU_pass_shader_get(mat->pass) != nullptr);
808 return true;
809 }
810 return false;
811}
812
814{
815 /* If shader is flagged for skipping optimization or has already been successfully
816 * optimized, skip. */
818 return;
819 }
820
821 /* If original shader has not been fully compiled, we are not
822 * ready to perform optimization. */
823 if (mat->status != GPU_MAT_SUCCESS) {
824 /* Reset optimization status. */
826 return;
827 }
828
829#if ASYNC_OPTIMIZED_PASS_CREATION == 1
830 /* If the optimized pass is not valid, first generate optimized pass.
831 * NOTE(Threading): Need to verify if GPU_generate_pass can cause side-effects, especially when
832 * used with "thunk". So far, this appears to work, and deferring optimized pass creation is more
833 * optimal, as these do not benefit from caching, due to baked constants. However, this could
834 * possibly be cause for concern for certain cases. */
835 if (!mat->optimized_pass) {
837 &mat->graph,
838 mat->engine,
839 mat->optimize_pass_info.callback,
840 mat->optimize_pass_info.thunk,
841 true);
843 }
844#else
845 if (!mat->optimized_pass) {
846 /* Optimized pass has not been created, skip future optimization attempts. */
848 return;
849 }
850#endif
851
852 bool success;
853/* NOTE: The shader may have already been compiled here since we are
854 * sharing GPUShader across GPUMaterials. In this case it's a no-op. */
855#ifndef NDEBUG
856 success = GPU_pass_compile(mat->optimized_pass, mat->name);
857#else
858 success = GPU_pass_compile(mat->optimized_pass, __func__);
859#endif
860
861 if (success) {
863 if (sh != nullptr) {
875 GPUShader *parent_sh = GPU_pass_shader_get(mat->pass);
876 if (parent_sh) {
877 GPU_shader_set_parent(sh, parent_sh);
878 GPU_shader_warm_cache(sh, -1);
879 }
880
881 /* Mark as complete. */
883 }
884 else {
885 /* Optimized pass failed to compile. Disable any future optimization attempts. */
887 }
888 }
889 else {
890 /* Optimization pass generation failed. Disable future attempts to optimize. */
892 mat->optimized_pass = nullptr;
894 }
895
896 /* Release node graph as no longer needed. */
898}
899
901{
902 LISTBASE_FOREACH (Material *, ma, &bmain->materials) {
903 GPU_material_free(&ma->gpumaterial);
904 }
905
906 LISTBASE_FOREACH (World *, wo, &bmain->worlds) {
907 GPU_material_free(&wo->gpumaterial);
908 }
909
911}
912
914 ConstructGPUMaterialFn construct_function_cb,
915 GPUCodegenCallbackFn generate_code_function_cb,
916 void *thunk)
917{
918 /* Allocate a new material and its material graph, and initialize its reference count. */
919 GPUMaterial *material = static_cast<GPUMaterial *>(
920 MEM_callocN(sizeof(GPUMaterial), "GPUMaterial"));
922 BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "GPUNodeGraph.used_libraries");
923 material->refcount = 1;
924 material->optimization_status = GPU_MAT_OPTIMIZATION_SKIP;
925 material->optimized_pass = nullptr;
926 material->default_mat = nullptr;
927 material->engine = engine;
928
929 /* Construct the material graph by adding and linking the necessary GPU material nodes. */
930 construct_function_cb(thunk, material);
931
932 /* Create and initialize the texture storing color bands used by Ramp and Curve nodes. */
934
935 /* Lookup an existing pass in the cache or generate a new one. */
936 material->pass = GPU_generate_pass(
937 material, &material->graph, material->engine, generate_code_function_cb, thunk, false);
938 material->optimized_pass = nullptr;
939
940 /* The pass already exists in the pass cache but its shader already failed to compile. */
941 if (material->pass == nullptr) {
942 material->status = GPU_MAT_FAILED;
943 gpu_node_graph_free(&material->graph);
944 return material;
945 }
946
947 /* The pass already exists in the pass cache and its shader is already compiled. */
948 GPUShader *shader = GPU_pass_shader_get(material->pass);
949 if (shader != nullptr) {
950 material->status = GPU_MAT_SUCCESS;
951 if (material->optimization_status == GPU_MAT_OPTIMIZATION_SKIP) {
952 /* Only free node graph if not required by secondary optimization pass. */
953 gpu_node_graph_free_nodes(&material->graph);
954 }
955 return material;
956 }
957
958 /* The material was created successfully but still needs to be compiled. */
959 material->status = GPU_MAT_CREATED;
960 return material;
961}
General operations, lookup, etc. for materials.
void BKE_material_defaults_free_gpu(void)
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_STATIC_ASSERT_ALIGN(st, align)
Definition BLI_assert.h:90
unsigned int BLI_ghashutil_ptrhash(const void *key)
GSet * BLI_gset_new(GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.c:944
bool BLI_ghashutil_ptrcmp(const void *a, const void *b)
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define LISTBASE_FOREACH(type, var, list)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:496
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define STRNCPY(dst, src)
Definition BLI_string.h:593
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:597
Platform independent time functions.
double BLI_time_now_seconds(void)
Definition time.c:65
#define UNUSED_VARS_NDEBUG(...)
#define ELEM(...)
#define GPU_SKY_WIDTH
#define GPU_SKY_HEIGHT
#define CM_TABLE
void(*)(void *thunk, GPUMaterial *material) ConstructGPUMaterialFn
eGPUMaterialEngine
eGPUMaterialFlag
@ GPU_MATFLAG_UPDATED
@ GPU_MATFLAG_GLOSSY
@ GPU_MATFLAG_COAT
@ GPU_MATFLAG_LOOKDEV_HACK
eGPUMaterialStatus
@ GPU_MAT_QUEUED
@ GPU_MAT_FAILED
@ GPU_MAT_SUCCESS
@ GPU_MAT_CREATED
void(*)(void *thunk, GPUMaterial *mat, GPUCodegenOutput *codegen) GPUCodegenCallbackFn
eGPUMaterialOptimizationStatus
@ GPU_MAT_OPTIMIZATION_READY
@ GPU_MAT_OPTIMIZATION_SUCCESS
@ GPU_MAT_OPTIMIZATION_SKIP
GPUPass *(*)(void *thunk, GPUMaterial *mat) GPUMaterialPassReplacementCallbackFn
eGPUType
@ GPU_VEC4
@ GPU_VEC3
@ GPU_FLOAT
bool GPU_link(GPUMaterial *mat, const char *name,...)
void GPU_shader_set_parent(GPUShader *shader, GPUShader *parent)
void GPU_shader_warm_cache(GPUShader *shader, int limit)
void GPU_texture_free(GPUTexture *texture)
@ GPU_TEXTURE_USAGE_SHADER_READ
GPUTexture * GPU_texture_create_2d_array(const char *name, int width, int height, int layer_len, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
GPUTexture * GPU_texture_create_1d_array(const char *name, int width, int layer_len, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
GPUUniformBuf * GPU_uniformbuf_create_ex(size_t size, const void *data, const char *name)
#define GPU_uniformbuf_create(size)
void GPU_uniformbuf_free(GPUUniformBuf *ubo)
GPUUniformBuf * GPU_uniformbuf_create_from_list(ListBase *inputs, const char *name)
Read Guarded memory(de)allocation.
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
ATOMIC_INLINE uint32_t atomic_add_and_fetch_uint32(uint32_t *p, uint32_t x)
ATOMIC_INLINE uint32_t atomic_sub_and_fetch_uint32(uint32_t *p, uint32_t x)
struct GPUShader GPUShader
additional_info("compositor_sum_float_shared") .push_constant(Type additional_info("compositor_sum_float_shared") .push_constant(Type GPU_RGBA32F
#define printf
Material material
DEGForeachIDComponentCallback callback
draw_view in_light_buf[] float
GPUPass * GPU_generate_pass(GPUMaterial *material, GPUNodeGraph *graph, eGPUMaterialEngine engine, GPUCodegenCallbackFn finalize_source_cb, void *thunk, bool optimize_graph)
void GPU_pass_release(GPUPass *pass)
void GPU_pass_acquire(GPUPass *pass)
void GPU_pass_begin_async_compilation(GPUPass *pass, const char *shname)
bool GPU_pass_compile(GPUPass *pass, const char *shname)
bool GPU_pass_async_compilation_try_finalize(GPUPass *pass)
bool GPU_pass_should_optimize(GPUPass *pass)
GPUShader * GPU_pass_shader_get(GPUPass *pass)
char * GPU_material_split_sub_function(GPUMaterial *material, eGPUType return_type, GPUNodeLink **link)
uint64_t GPU_material_uuid_get(GPUMaterial *mat)
static void gpu_material_ramp_texture_build(GPUMaterial *mat)
bool GPU_material_async_try_finalize(GPUMaterial *mat)
void GPU_material_acquire(GPUMaterial *mat)
void GPU_material_compile(GPUMaterial *mat)
ListBase GPU_material_attributes(const GPUMaterial *material)
void GPU_material_output_surface(GPUMaterial *material, GPUNodeLink *link)
GPUPass * GPU_material_get_pass(GPUMaterial *material)
void GPU_material_async_compile(GPUMaterial *mat)
bool GPU_material_has_surface_output(GPUMaterial *mat)
void GPU_material_status_set(GPUMaterial *mat, eGPUMaterialStatus status)
void GPU_material_free_single(GPUMaterial *material)
GPUTexture ** gpu_material_ramp_texture_row_set(GPUMaterial *mat, int size, const float *pixels, float *r_row)
void GPU_materials_free(Main *bmain)
void GPU_material_free(ListBase *gpumaterial)
void GPU_material_output_displacement(GPUMaterial *material, GPUNodeLink *link)
const ListBase * GPU_material_layer_attributes(const GPUMaterial *material)
void GPU_material_output_thickness(GPUMaterial *material, GPUNodeLink *link)
GPUShader * GPU_material_get_shader(GPUMaterial *material)
void GPU_material_optimize(GPUMaterial *mat)
void GPU_material_add_output_link_aov(GPUMaterial *material, GPUNodeLink *link, int hash)
bool GPU_material_optimization_ready(GPUMaterial *mat)
#define MAX_GPU_SKIES
bool GPU_material_flag_get(const GPUMaterial *mat, eGPUMaterialFlag flag)
Scene * GPU_material_scene(GPUMaterial *material)
bool GPU_material_recalc_flag_get(GPUMaterial *mat)
GPUShader * GPU_material_get_shader_base(GPUMaterial *material)
ListBase GPU_material_textures(GPUMaterial *material)
void GPU_material_add_output_link_composite(GPUMaterial *material, GPUNodeLink *link)
bool GPU_material_sss_profile_create(GPUMaterial *material, float radii[3])
static void gpu_material_finalize(GPUMaterial *mat, bool success)
GPUMaterial * GPU_material_from_callbacks(eGPUMaterialEngine engine, ConstructGPUMaterialFn construct_function_cb, GPUCodegenCallbackFn generate_code_function_cb, void *thunk)
GPUTexture ** gpu_material_sky_texture_layer_set(GPUMaterial *mat, int width, int height, const float *pixels, float *row)
void GPU_material_release(GPUMaterial *mat)
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)
eGPUMaterialStatus GPU_material_status(GPUMaterial *mat)
void GPU_material_flag_set(GPUMaterial *mat, eGPUMaterialFlag flag)
Material * GPU_material_get_material(GPUMaterial *material)
#define SSS_SAMPLES
void GPU_material_output_volume(GPUMaterial *material, GPUNodeLink *link)
eGPUMaterialFlag GPU_material_flag(const GPUMaterial *mat)
static void gpu_material_sky_texture_build(GPUMaterial *mat)
void GPU_material_optimization_status_set(GPUMaterial *mat, eGPUMaterialOptimizationStatus status)
const char * GPU_material_get_name(GPUMaterial *material)
void GPU_material_set_default(GPUMaterial *material, GPUMaterial *default_material)
const GPUUniformAttrList * GPU_material_uniform_attributes(const GPUMaterial *material)
bool GPU_material_has_displacement_output(GPUMaterial *mat)
GPUNodeGraph * gpu_material_node_graph(GPUMaterial *material)
void GPU_material_uniform_buffer_create(GPUMaterial *material, ListBase *inputs)
#define MAX_COLOR_BAND
GPUUniformBuf * GPU_material_uniform_buffer_get(GPUMaterial *material)
bool GPU_material_has_volume_output(GPUMaterial *mat)
eGPUMaterialOptimizationStatus GPU_material_optimization_status(GPUMaterial *mat)
void gpu_node_graph_free(GPUNodeGraph *graph)
void gpu_node_graph_free_nodes(GPUNodeGraph *graph)
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
void node_tree_free_local_tree(bNodeTree *ntree)
Definition node.cc:3639
bNodeTree * node_tree_localize(bNodeTree *ntree, ID *new_owner_id)
Definition node.cc:3750
#define hash
Definition noise.c:154
unsigned int uint32_t
Definition stdint.h:80
unsigned __int64 uint64_t
Definition stdint.h:90
float pixels[MAX_COLOR_BAND][CM_TABLE+1][4]
GPUSkyBuilder * sky_builder
GPUUniformBuf * ubo
int generated_function_len
GPUColorBandBuilder * coba_builder
float sss_radii[3]
GPUTexture * sss_tex_profile
bool has_displacement_output
eGPUMaterialFlag flag
uint32_t refcount
GPUUniformBuf * sss_profile
bool do_batch_compilation
bool has_volume_output
bool has_surface_output
eGPUMaterialOptimizationStatus optimization_status
GPUTexture * coba_tex
Material * ma
GPUPass * optimized_pass
double creation_time
uint64_t uuid
char name[64]
GPUTexture * sky_tex
GPUMaterial * default_mat
GPUPass * pass
GPUNodeGraph graph
bool is_volume_shader
eGPUMaterialEngine engine
eGPUMaterialStatus status
float pixels[MAX_GPU_SKIES][GPU_SKY_WIDTH *GPU_SKY_HEIGHT][4]
float kernel[SSS_SAMPLES][4]
void * py_instance
Definition DNA_ID.h:482
void * data
ListBase materials
Definition BKE_main.hh:216
ListBase worlds
Definition BKE_main.hh:224
void * DRW_deferred_shader_remove
Definition stubs.c:39
void * ntreeGPUMaterialNodes
Definition stubs.c:42
uint8_t flag
Definition wm_window.cc:138