Blender V4.3
eevee_instance.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
11#include <sstream>
12
13#include "BKE_global.hh"
14#include "BKE_object.hh"
15#include "BLI_rect.h"
16#include "BLT_translation.hh"
18#include "DNA_ID.h"
20#include "DNA_modifier_types.h"
21#include "IMB_imbuf_types.hh"
22#include "RE_pipeline.h"
23
24#include "eevee_engine.h"
25#include "eevee_instance.hh"
26
27#include "DNA_particle_types.h"
28
29#include "draw_common.hh"
30
31namespace blender::eevee {
32
33void *Instance::debug_scope_render_sample = nullptr;
34void *Instance::debug_scope_irradiance_setup = nullptr;
35void *Instance::debug_scope_irradiance_sample = nullptr;
36
37/* -------------------------------------------------------------------- */
47void Instance::init(const int2 &output_res,
48 const rcti *output_rect,
49 const rcti *visible_rect,
50 RenderEngine *render_,
51 Depsgraph *depsgraph_,
52 Object *camera_object_,
53 const RenderLayer *render_layer_,
54 const DRWView *drw_view_,
55 const View3D *v3d_,
56 const RegionView3D *rv3d_)
57{
58 render = render_;
59 depsgraph = depsgraph_;
60 camera_orig_object = camera_object_;
61 render_layer = render_layer_;
62 drw_view = drw_view_;
63 v3d = v3d_;
64 rv3d = rv3d_;
66 update_eval_members();
67
68 info_ = "";
69
70 shaders_are_ready_ = shaders.is_ready(is_image_render());
71 if (!shaders_are_ready_) {
72 return;
73 }
74
75 if (assign_if_different(debug_mode, (eDebugMode)G.debug_value)) {
76 sampling.reset();
77 }
78 if (output_res != film.display_extent_get()) {
79 sampling.reset();
80 }
81 if (output_rect) {
82 int2 offset = int2(output_rect->xmin, output_rect->ymin);
83 int2 extent = int2(BLI_rcti_size_x(output_rect), BLI_rcti_size_y(output_rect));
84 if (offset != film.get_data().offset || extent != film.get_data().extent) {
85 sampling.reset();
86 }
87 }
88 if (assign_if_different(overlays_enabled_, v3d && !(v3d->flag2 & V3D_HIDE_OVERLAYS))) {
89 sampling.reset();
90 }
91 if (is_painting()) {
92 sampling.reset();
93 }
94 if (is_navigating() && scene->eevee.flag & SCE_EEVEE_SHADOW_JITTERED_VIEWPORT) {
95 sampling.reset();
96 }
97
98 sampling.init(scene);
99 camera.init();
100 film.init(output_res, output_rect);
103 velocity.init();
106 shadows.init();
108 main_view.init();
111 /* Irradiance Cache needs reflection probes to be initialized. */
114 volume.init();
115 lookdev.init(visible_rect);
116
117 /* Pre-compile specialization constants in parallel (if supported). */
118 shaders.precompile_specializations(
119 render_buffers.data.shadow_id, shadows.get_data().ray_count, shadows.get_data().step_count);
120 shaders_are_ready_ = shaders.is_ready(is_image_render());
121}
122
123void Instance::init_light_bake(Depsgraph *depsgraph, draw::Manager *manager)
124{
125 this->depsgraph = depsgraph;
126 this->manager = manager;
127 camera_orig_object = nullptr;
128 render = nullptr;
129 render_layer = nullptr;
130 drw_view = nullptr;
131 v3d = nullptr;
132 rv3d = nullptr;
133 update_eval_members();
134
135 is_light_bake = true;
136 debug_mode = (eDebugMode)G.debug_value;
137 info_ = "";
138
139 shaders.is_ready(true);
140
141 sampling.init(scene);
142 camera.init();
143 /* Film isn't used but init to avoid side effects in other module. */
144 rcti empty_rect{0, 0, 0, 0};
145 film.init(int2(1), &empty_rect);
147 velocity.init();
149 shadows.init();
150 main_view.init();
153 /* Irradiance Cache needs reflection probes to be initialized. */
156 volume.init();
157 lookdev.init(&empty_rect);
158}
159
160void Instance::set_time(float time)
161{
162 BLI_assert(render);
163 DRW_render_set_time(render, depsgraph, floorf(time), fractf(time));
164 update_eval_members();
165}
166
167void Instance::update_eval_members()
168{
173 nullptr;
174}
175
176void Instance::view_update()
177{
178 sampling.reset();
179}
180
183/* -------------------------------------------------------------------- */
192{
193 if (!shaders_are_ready_) {
194 return;
195 }
196
197 /* Needs to be first for sun light parameters. */
198 world.sync();
199
200 materials.begin_sync();
201 velocity.begin_sync(); /* NOTE: Also syncs camera. */
203 shadows.begin_sync();
204 volume.begin_sync();
209
214 main_view.sync();
215 film.sync();
218 lookdev.sync();
219
223
224 if (is_light_bake) {
225 /* Do not use render layer visibility during bake.
226 * NOTE: This is arbitrary and could be changed if needed. */
228 }
229
231 sampling.reset();
232 }
233}
234
236{
237 if (!shaders_are_ready_) {
238 return;
239 }
240
241 const bool is_renderable_type = ELEM(ob->type,
242 OB_CURVES,
244 OB_MESH,
246 OB_VOLUME,
247 OB_LAMP,
249 const bool is_drawable_type = is_renderable_type && !ELEM(ob->type, OB_LAMP, OB_LIGHTPROBE);
250 const int ob_visibility = DRW_object_visibility_in_active_context(ob);
251 const bool partsys_is_visible = (ob_visibility & OB_VISIBLE_PARTICLES) != 0 &&
252 (ob->type == OB_MESH);
253 const bool object_is_visible = DRW_object_is_renderable(ob) &&
254 (ob_visibility & OB_VISIBLE_SELF) != 0;
255
256 if (!is_renderable_type || (!partsys_is_visible && !object_is_visible)) {
257 return;
258 }
259
260 /* TODO cleanup. */
261 ObjectRef ob_ref = DRW_object_ref_get(ob);
262 ObjectHandle &ob_handle = sync.sync_object(ob_ref);
263 ResourceHandle res_handle = {0};
264 if (is_drawable_type) {
265 res_handle = manager->resource_handle(ob_ref);
266 }
267
268 if (partsys_is_visible && ob != DRW_context_state_get()->object_edit) {
269 auto sync_hair =
270 [&](ObjectHandle hair_handle, ModifierData &md, ParticleSystem &particle_sys) {
271 ResourceHandle _res_handle = manager->resource_handle_for_psys(ob_ref,
272 ob->object_to_world());
273 sync.sync_curves(ob, hair_handle, _res_handle, ob_ref, &md, &particle_sys);
274 };
275 foreach_hair_particle_handle(ob, ob_handle, sync_hair);
276 }
277
278 if (object_is_visible) {
279 switch (ob->type) {
280 case OB_LAMP:
281 lights.sync_light(ob, ob_handle);
282 break;
283 case OB_MESH:
284 if (!sync.sync_sculpt(ob, ob_handle, res_handle, ob_ref)) {
285 sync.sync_mesh(ob, ob_handle, res_handle, ob_ref);
286 }
287 break;
288 case OB_POINTCLOUD:
289 sync.sync_point_cloud(ob, ob_handle, res_handle, ob_ref);
290 break;
291 case OB_VOLUME:
292 sync.sync_volume(ob, ob_handle, res_handle, ob_ref);
293 break;
294 case OB_CURVES:
295 sync.sync_curves(ob, ob_handle, res_handle, ob_ref);
296 break;
297 case OB_LIGHTPROBE:
298 light_probes.sync_probe(ob, ob_handle);
299 break;
300 default:
301 break;
302 }
303 }
304}
305
306void Instance::object_sync_render(void *instance_,
307 Object *ob,
308 RenderEngine *engine,
309 Depsgraph *depsgraph)
310{
311 UNUSED_VARS(engine, depsgraph);
312 Instance &inst = *reinterpret_cast<Instance *>(instance_);
313 inst.object_sync(ob);
314}
315
317{
318 if (!shaders_are_ready_) {
319 return;
320 }
321
323 volume.end_sync(); /* Needs to be before shadows. */
324 shadows.end_sync(); /* Needs to be before lights. */
326 sampling.end_sync();
328 film.end_sync();
334
336
337 depsgraph_last_update_ = DEG_get_update_count(depsgraph);
338}
339
340void Instance::render_sync()
341{
342 /* TODO: Remove old draw manager calls. */
344
346
349
350 begin_sync();
351
352 DRW_render_object_iter(this, render, depsgraph, object_sync_render);
353
358
360
361 end_sync();
362
363 manager->end_sync();
364
365 /* TODO: Remove old draw manager calls. */
367
369}
370
371bool Instance::needs_lightprobe_sphere_passes() const
372{
373 return sphere_probes.update_probes_this_sample_;
374}
375
376bool Instance::do_lightprobe_sphere_sync() const
377{
378 return (materials.queued_shaders_count == 0) && needs_lightprobe_sphere_passes();
379}
380
381bool Instance::needs_planar_probe_passes() const
382{
383 return planar_probes.update_probes_;
384}
385
386bool Instance::do_planar_probe_sync() const
387{
388 return (materials.queued_shaders_count == 0) && needs_planar_probe_passes();
389}
390
393/* -------------------------------------------------------------------- */
397void Instance::render_sample()
398{
399 if (sampling.finished_viewport()) {
400 film.display();
402 return;
403 }
404
405 /* Motion blur may need to do re-sync after a certain number of sample. */
406 if (!is_viewport() && sampling.do_render_sync()) {
407 render_sync();
408 }
409
410 DebugScope debug_scope(debug_scope_render_sample, "EEVEE.render_sample");
411
412 sampling.step();
413
416
418
420
422}
423
424void Instance::render_read_result(RenderLayer *render_layer, const char *view_name)
425{
426 eViewLayerEEVEEPassType pass_bits = film.enabled_passes_get();
427
428 for (auto i : IndexRange(EEVEE_RENDER_PASS_MAX_BIT + 1)) {
429 eViewLayerEEVEEPassType pass_type = eViewLayerEEVEEPassType(pass_bits & (1 << i));
430 if (pass_type == 0) {
431 continue;
432 }
433
434 Vector<std::string> pass_names = Film::pass_to_render_pass_names(pass_type, view_layer);
435 for (int64_t pass_offset : IndexRange(pass_names.size())) {
437 render_layer, pass_names[pass_offset].c_str(), view_name);
438 if (!rp) {
439 continue;
440 }
441 float *result = film.read_pass(pass_type, pass_offset);
442
443 if (result) {
444 BLI_mutex_lock(&render->update_render_passes_mutex);
445 /* WORKAROUND: We use texture read to avoid using a frame-buffer to get the render result.
446 * However, on some implementation, we need a buffer with a few extra bytes for the read to
447 * happen correctly (see #GLTexture::read()). So we need a custom memory allocation. */
448 /* Avoid `memcpy()`, replace the pointer directly. */
449 RE_pass_set_buffer_data(rp, result);
450 BLI_mutex_unlock(&render->update_render_passes_mutex);
451 }
452 }
453 }
454
455 /* AOVs. */
457 if ((aov->flag & AOV_CONFLICT) != 0) {
458 continue;
459 }
460 RenderPass *rp = RE_pass_find_by_name(render_layer, aov->name, view_name);
461 if (!rp) {
462 continue;
463 }
464 float *result = film.read_aov(aov);
465
466 if (result) {
467 BLI_mutex_lock(&render->update_render_passes_mutex);
468 /* WORKAROUND: We use texture read to avoid using a frame-buffer to get the render result.
469 * However, on some implementation, we need a buffer with a few extra bytes for the read to
470 * happen correctly (see #GLTexture::read()). So we need a custom memory allocation. */
471 /* Avoid #memcpy(), replace the pointer directly. */
472 RE_pass_set_buffer_data(rp, result);
473 BLI_mutex_unlock(&render->update_render_passes_mutex);
474 }
475 }
476
477 /* The vector pass is initialized to weird values. Set it to neutral value if not rendered. */
478 if ((pass_bits & EEVEE_RENDER_PASS_VECTOR) == 0) {
479 for (const std::string &vector_pass_name :
480 Film::pass_to_render_pass_names(EEVEE_RENDER_PASS_VECTOR, view_layer))
481 {
482 RenderPass *vector_rp = RE_pass_find_by_name(
483 render_layer, vector_pass_name.c_str(), view_name);
484 if (vector_rp) {
485 memset(vector_rp->ibuf->float_buffer.data,
486 0,
487 sizeof(float) * 4 * vector_rp->rectx * vector_rp->recty);
488 }
489 }
490 }
491}
492
495/* -------------------------------------------------------------------- */
499void Instance::render_frame(RenderEngine *engine, RenderLayer *render_layer, const char *view_name)
500{
501 /* TODO: Break on RE_engine_test_break(engine) */
502 while (!sampling.finished()) {
503 if (materials.queued_shaders_count > 0) {
504 /* Leave some time for shaders to compile. */
507 this->render_sync();
508 continue;
509 }
510
511 this->render_sample();
512
513 if ((sampling.sample_index() == 1) || ((sampling.sample_index() % 25) == 0) ||
514 sampling.finished())
515 {
516 /* TODO: Use `fmt`. */
517 std::string re_info = "Rendering " + std::to_string(sampling.sample_index()) + " / " +
518 std::to_string(sampling.sample_count()) + " samples";
519 RE_engine_update_stats(engine, nullptr, re_info.c_str());
520 }
521
522 /* Perform render step between samples to allow
523 * flushing of freed GPUBackend resources. */
525 GPU_flush();
526 }
528
529#if 0
530 /* TODO(fclem) print progression. */
531 RE_engine_update_progress(engine, float(sampling.sample_index()) / float(sampling.sample_count()));
532 /* TODO(fclem): Does not currently work. But would be better to just display to 2D view like
533 * cycles does. */
534 if (G.background == false && first_read) {
535 /* Allow to preview the first sample. */
536 /* TODO(fclem): Might want to not do this during animation render to avoid too much stall. */
537 this->render_read_result(render_layer, view_name);
538 first_read = false;
539 DRW_render_context_disable(render->re);
540 /* Allow the 2D viewport to grab the ticket mutex to display the render. */
541 DRW_render_context_enable(render->re);
542 }
543#endif
544 }
545
546 this->film.cryptomatte_sort();
547
548 this->render_read_result(render_layer, view_name);
549
550 if (!info_.empty()) {
552 engine, RPT_("Errors during render. See the System Console for more info."));
553 printf("%s", info_.c_str());
554 info_ = "";
555 }
556}
557
558void Instance::draw_viewport()
559{
560 if (!shaders_are_ready_) {
563 info_append_i18n("Compiling EEVEE engine shaders");
565 return;
566 }
567
568 render_sample();
570
571 if (this->film.is_viewport_compositor_enabled()) {
572 this->film.write_viewport_compositor_passes();
573 }
574
575 /* Do not request redraw during viewport animation to lock the frame-rate to the animation
576 * playback rate. This is in order to preserve motion blur aspect and also to avoid TAA reset
577 * that can show flickering. */
578 if (!sampling.finished_viewport() && !DRW_state_is_playback()) {
580 }
581
582 if (materials.queued_shaders_count > 0) {
583 info_append_i18n("Compiling shaders ({} remaining)", materials.queued_shaders_count);
584
587 {
589 "Increasing Preferences > System > Max Shader Compilation Subprocesses may improve "
590 "compilation time.");
591 }
593 }
594 else if (materials.queued_optimize_shaders_count > 0) {
595 info_append_i18n("Optimizing shaders ({} remaining)", materials.queued_optimize_shaders_count);
596 }
597}
598
599void Instance::draw_viewport_image_render()
600{
601 while (!sampling.finished_viewport()) {
602 this->render_sample();
603 }
605
606 if (this->film.is_viewport_compositor_enabled()) {
607 this->film.write_viewport_compositor_passes();
608 }
609}
610
611void Instance::store_metadata(RenderResult *render_result)
612{
613 cryptomatte.store_metadata(render_result);
614}
615
616void Instance::update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer)
617{
619
620#define CHECK_PASS_LEGACY(name, type, channels, chanid) \
621 if (view_layer->passflag & (SCE_PASS_##name)) { \
622 RE_engine_register_pass( \
623 engine, scene, view_layer, RE_PASSNAME_##name, channels, chanid, type); \
624 } \
625 ((void)0)
626#define CHECK_PASS_EEVEE(name, type, channels, chanid) \
627 if (view_layer->eevee.render_passes & (EEVEE_RENDER_PASS_##name)) { \
628 RE_engine_register_pass( \
629 engine, scene, view_layer, RE_PASSNAME_##name, channels, chanid, type); \
630 } \
631 ((void)0)
632
633 CHECK_PASS_LEGACY(Z, SOCK_FLOAT, 1, "Z");
634 CHECK_PASS_LEGACY(MIST, SOCK_FLOAT, 1, "Z");
635 CHECK_PASS_LEGACY(NORMAL, SOCK_VECTOR, 3, "XYZ");
636 CHECK_PASS_LEGACY(POSITION, SOCK_VECTOR, 3, "XYZ");
637 CHECK_PASS_LEGACY(VECTOR, SOCK_VECTOR, 4, "XYZW");
638 CHECK_PASS_LEGACY(DIFFUSE_DIRECT, SOCK_RGBA, 3, "RGB");
639 CHECK_PASS_LEGACY(DIFFUSE_COLOR, SOCK_RGBA, 3, "RGB");
640 CHECK_PASS_LEGACY(GLOSSY_DIRECT, SOCK_RGBA, 3, "RGB");
641 CHECK_PASS_LEGACY(GLOSSY_COLOR, SOCK_RGBA, 3, "RGB");
642 CHECK_PASS_EEVEE(VOLUME_LIGHT, SOCK_RGBA, 3, "RGB");
643 CHECK_PASS_LEGACY(EMIT, SOCK_RGBA, 3, "RGB");
644 CHECK_PASS_LEGACY(ENVIRONMENT, SOCK_RGBA, 3, "RGB");
645 CHECK_PASS_LEGACY(SHADOW, SOCK_RGBA, 3, "RGB");
646 CHECK_PASS_LEGACY(AO, SOCK_RGBA, 3, "RGB");
647 CHECK_PASS_EEVEE(TRANSPARENT, SOCK_RGBA, 4, "RGBA");
648
650 if ((aov->flag & AOV_CONFLICT) != 0) {
651 continue;
652 }
653 switch (aov->type) {
654 case AOV_TYPE_COLOR:
655 RE_engine_register_pass(engine, scene, view_layer, aov->name, 4, "RGBA", SOCK_RGBA);
656 break;
657 case AOV_TYPE_VALUE:
658 RE_engine_register_pass(engine, scene, view_layer, aov->name, 1, "X", SOCK_FLOAT);
659 break;
660 default:
661 break;
662 }
663 }
664
665 /* NOTE: Name channels lowercase `rgba` so that compression rules check in OpenEXR DWA code uses
666 * lossless compression. Reportedly this naming is the only one which works good from the
667 * interoperability point of view. Using `xyzw` naming is not portable. */
668 auto register_cryptomatte_passes = [&](eViewLayerCryptomatteFlags cryptomatte_layer,
669 eViewLayerEEVEEPassType eevee_pass) {
670 if (view_layer->cryptomatte_flag & cryptomatte_layer) {
671 for (const std::string &pass_name : Film::pass_to_render_pass_names(eevee_pass, view_layer))
672 {
674 engine, scene, view_layer, pass_name.c_str(), 4, "rgba", SOCK_RGBA);
675 }
676 }
677 };
680 register_cryptomatte_passes(VIEW_LAYER_CRYPTOMATTE_MATERIAL,
682}
683
684void Instance::light_bake_irradiance(
685 Object &probe,
686 FunctionRef<void()> context_enable,
687 FunctionRef<void()> context_disable,
688 FunctionRef<bool()> stop,
689 FunctionRef<void(LightProbeGridCacheFrame *, float progress)> result_update)
690{
692
693 auto custom_pipeline_wrapper = [&](FunctionRef<void()> callback) {
694 context_enable();
696 callback();
698 context_disable();
699 };
700
701 auto context_wrapper = [&](FunctionRef<void()> callback) {
702 context_enable();
703 callback();
704 context_disable();
705 };
706
707 volume_probes.bake.init(probe);
708
709 custom_pipeline_wrapper([&]() {
711 render_sync();
712 manager->end_sync();
713
714 /* Sampling module needs to be initialized to computing lighting. */
715 sampling.init(probe);
716 sampling.step();
717
718 DebugScope debug_scope(debug_scope_irradiance_setup, "EEVEE.irradiance_setup");
719
721
723
725 return;
726 }
727
729
732 });
733
735 return;
736 }
737
738 sampling.init(probe);
739 while (!sampling.finished()) {
740 context_wrapper([&]() {
741 DebugScope debug_scope(debug_scope_irradiance_sample, "EEVEE.irradiance_sample");
742
743 /* Batch ray cast by pack of 16. Avoids too much overhead of the update function & context
744 * switch. */
745 /* TODO(fclem): Could make the number of iteration depend on the computation time. */
746 for (int i = 0; i < 16 && !sampling.finished(); i++) {
747 sampling.step();
748
752 }
753
754 LightProbeGridCacheFrame *cache_frame;
755 if (sampling.finished()) {
756 cache_frame = volume_probes.bake.read_result_packed();
757 }
758 else {
759 /* TODO(fclem): Only do this read-back if needed. But it might be tricky to know when. */
761 }
762
763 float progress = sampling.sample_index() / float(sampling.sample_count());
764 result_update(cache_frame, progress);
765 });
766
767 if (stop()) {
768 return;
769 }
770 }
771}
772
775} // namespace blender::eevee
General operations, lookup, etc. for blender objects.
@ OB_VISIBLE_SELF
@ OB_VISIBLE_PARTICLES
#define BLI_assert(a)
Definition BLI_assert.h:50
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition BLI_rect.h:193
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition BLI_rect.h:189
void BLI_mutex_lock(ThreadMutex *mutex)
Definition threads.cc:345
void BLI_mutex_unlock(ThreadMutex *mutex)
Definition threads.cc:350
void BLI_time_sleep_ms(int ms)
Definition time.c:85
#define UNUSED_VARS(...)
#define ELEM(...)
#define RPT_(msgid)
uint64_t DEG_get_update_count(const Depsgraph *depsgraph)
Definition depsgraph.cc:350
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
ViewLayer * DEG_get_evaluated_view_layer(const Depsgraph *graph)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
ID and Library types, which are fundamental for SDNA.
eViewLayerCryptomatteFlags
@ VIEW_LAYER_CRYPTOMATTE_MATERIAL
@ VIEW_LAYER_CRYPTOMATTE_ASSET
@ VIEW_LAYER_CRYPTOMATTE_OBJECT
#define EEVEE_RENDER_PASS_MAX_BIT
eViewLayerEEVEEPassType
@ EEVEE_RENDER_PASS_CRYPTOMATTE_MATERIAL
@ EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT
@ EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET
@ EEVEE_RENDER_PASS_VECTOR
@ AOV_TYPE_COLOR
@ AOV_TYPE_VALUE
@ AOV_CONFLICT
@ SOCK_VECTOR
@ SOCK_FLOAT
@ SOCK_RGBA
@ OB_GREASE_PENCIL
@ OB_LAMP
@ OB_MESH
@ OB_POINTCLOUD
@ OB_VOLUME
@ OB_CURVES
@ OB_LIGHTPROBE
#define RE_PASSNAME_COMBINED
@ SCE_LAY_SOLID
@ SCE_LAY_STRAND
@ SCE_LAY_VOLUMES
@ SCE_EEVEE_SHADOW_JITTERED_VIEWPORT
@ V3D_HIDE_OVERLAYS
void DRW_render_context_disable(Render *render)
void DRW_render_context_enable(Render *render)
bool GPU_use_parallel_compilation()
void GPU_render_step()
eGPUBackendType GPU_backend_get_type()
void GPU_framebuffer_clear_color_depth(GPUFrameBuffer *fb, const float clear_col[4], float clear_depth)
@ GPU_DRIVER_ANY
bool GPU_type_matches_ex(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver, eGPUBackendType backend)
@ GPU_OS_ANY
@ GPU_DEVICE_ANY
void GPU_flush()
Definition gpu_state.cc:294
Contains defines and structs used throughout the imbuf module.
Definition film.h:30
ResourceHandle resource_handle_for_psys(const ObjectRef &ref, const float4x4 &model_matrix)
ResourceHandle resource_handle(const ObjectRef &ref, float inflate_bounds=0.0f)
void object_sync(ObjectRef &ob_ref, Manager &manager)
void store_metadata(RenderResult *render_result)
static const Vector< std::string > pass_to_render_pass_names(eViewLayerEEVEEPassType pass_type, const ViewLayer *view_layer)
A running instance of the engine.
VolumeProbeModule volume_probes
SphereProbeModule sphere_probes
AmbientOcclusion ambient_occlusion
void info_append_i18n(const char *msg, Args &&...args)
SubsurfaceModule subsurface
bool needs_lightprobe_sphere_passes() const
bool needs_planar_probe_passes() const
const RenderLayer * render_layer
void object_sync(Object *ob)
const RegionView3D * rv3d
PlanarProbeModule planar_probes
UniformDataModule uniform_data
LightProbeModule light_probes
MotionBlurModule motion_blur
void init(const Object &probe_object)
LightProbeGridCacheFrame * read_result_packed()
LightProbeGridCacheFrame * read_result_unpacked()
void surfels_create(const Object &probe_object)
void sync_light(const Object *ob, ObjectHandle &handle)
void sync_probe(const Object *ob, ObjectHandle &handle)
void init(const rcti *visible_rect)
void sync_point_cloud(Object *ob, ObjectHandle &ob_handle, ResourceHandle res_handle, const ObjectRef &ob_ref)
ObjectHandle & sync_object(const ObjectRef &ob_ref)
Definition eevee_sync.cc:37
void sync_mesh(Object *ob, ObjectHandle &ob_handle, ResourceHandle res_handle, const ObjectRef &ob_ref)
Definition eevee_sync.cc:91
void sync_volume(Object *ob, ObjectHandle &ob_handle, ResourceHandle res_handle, const ObjectRef &ob_ref)
void sync_curves(Object *ob, ObjectHandle &ob_handle, ResourceHandle res_handle, const ObjectRef &ob_ref, ModifierData *modifier_data=nullptr, ParticleSystem *particle_sys=nullptr)
bool sync_sculpt(Object *ob, ObjectHandle &ob_handle, ResourceHandle res_handle, const ObjectRef &ob_ref)
#define printf
const Depsgraph * depsgraph
DEGForeachIDComponentCallback callback
#define floorf(x)
blender::draw::Manager * DRW_manager_get()
blender::draw::ObjectRef DRW_object_ref_get(Object *object)
DefaultFramebufferList * DRW_viewport_framebuffer_list_get()
void DRW_cache_restart()
bool DRW_object_is_renderable(const Object *ob)
void DRW_render_instance_buffer_finish()
int DRW_object_visibility_in_active_context(const Object *ob)
void DRW_render_set_time(RenderEngine *engine, Depsgraph *depsgraph, int frame, float subframe)
const DRWContextState * DRW_context_state_get()
void DRW_viewport_request_redraw()
void DRW_custom_pipeline_end()
void DRW_render_object_iter(void *vedata, RenderEngine *engine, Depsgraph *depsgraph, void(*callback)(void *vedata, Object *ob, RenderEngine *engine, Depsgraph *depsgraph))
bool DRW_state_is_playback()
void DRW_custom_pipeline_begin(DrawEngineType *draw_engine_type, Depsgraph *depsgraph)
DrawEngineType draw_engine_eevee_next_type
#define CHECK_PASS_EEVEE(name, type, channels, chanid)
#define CHECK_PASS_LEGACY(name, type, channels, chanid)
draw_view in_light_buf[] float
void RE_engine_update_stats(RenderEngine *engine, const char *stats, const char *info)
void RE_engine_set_error_message(RenderEngine *engine, const char *msg)
void RE_engine_register_pass(RenderEngine *engine, Scene *scene, ViewLayer *view_layer, const char *name, int channels, const char *chanid, eNodeSocketDatatype type)
void RE_engine_update_progress(RenderEngine *engine, float progress)
MINLINE float fractf(float a)
#define G(x, y, z)
void hair_update(Manager &manager)
Definition draw_hair.cc:338
void DRW_curves_update()
void curves_update(Manager &manager)
void hair_free()
Definition draw_hair.cc:344
void hair_init()
Definition draw_hair.cc:272
void foreach_hair_particle_handle(Object *ob, ObjectHandle ob_handle, HairHandleCallback callback)
bool assign_if_different(T &old_value, T new_value)
VecBase< int32_t, 2 > int2
void RE_pass_set_buffer_data(RenderPass *pass, float *data)
RenderPass * RE_pass_find_by_name(RenderLayer *rl, const char *name, const char *viewname)
__int64 int64_t
Definition stdint.h:89
GPUFrameBuffer * default_fb
ImBufFloatBuffer float_buffer
char name[RE_MAXNAME]
Definition RE_pipeline.h:89
struct ImBuf * ibuf
Definition RE_pipeline.h:68
short cryptomatte_flag
ListBase aovs
char name[64]
int ymin
int xmin