Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorBrecht Van Lommel <brecht@blender.org>2021-09-20 18:59:20 +0300
committerBrecht Van Lommel <brecht@blender.org>2021-09-21 15:55:54 +0300
commit08031197250aeecbaca3803254e6f25b8c7b7b37 (patch)
tree6fe7ab045f0dc0a423d6557c4073f34309ef4740 /source
parentfa6b1007bad065440950cd67deb16a04f368856f (diff)
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity, new shadow catcher, revamped sampling settings, subsurface scattering anisotropy, new GPU volume sampling, improved PMJ sampling pattern, and more. Some features have also been removed or changed, breaking backwards compatibility. Including the removal of the OpenCL backend, for which alternatives are under development. Release notes and code docs: https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles https://wiki.blender.org/wiki/Source/Render/Cycles Credits: * Sergey Sharybin * Brecht Van Lommel * Patrick Mours (OptiX backend) * Christophe Hery (subsurface scattering anisotropy) * William Leeson (PMJ sampling pattern) * Alaska (various fixes and tweaks) * Thomas Dinges (various fixes) For the full commit history, see the cycles-x branch. This squashes together all the changes since intermediate changes would often fail building or tests. Ref T87839, T87837, T87836 Fixes T90734, T89353, T80267, T80267, T77185, T69800
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h2
-rw-r--r--source/blender/blenkernel/intern/layer.c1
-rw-r--r--source/blender/blenloader/intern/versioning_270.c16
-rw-r--r--source/blender/blenloader/intern/versioning_280.c2
-rw-r--r--source/blender/blenloader/intern/versioning_290.c1
-rw-r--r--source/blender/blenloader/intern/versioning_300.c33
-rw-r--r--source/blender/blenloader/intern/versioning_cycles.c26
-rw-r--r--source/blender/blenloader/intern/versioning_defaults.c11
-rw-r--r--source/blender/compositor/nodes/COM_IDMaskNode.cc4
-rw-r--r--source/blender/compositor/nodes/COM_ZCombineNode.cc4
-rw-r--r--source/blender/draw/DRW_engine.h3
-rw-r--r--source/blender/draw/engines/eevee/eevee_cryptomatte.c10
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h1
-rw-r--r--source/blender/draw/engines/external/external_engine.c202
-rw-r--r--source/blender/draw/engines/external/external_engine.h8
-rw-r--r--source/blender/draw/engines/select/select_engine.c2
-rw-r--r--source/blender/draw/engines/workbench/workbench_engine.c2
-rw-r--r--source/blender/draw/intern/DRW_render.h1
-rw-r--r--source/blender/draw/intern/draw_manager.c78
-rw-r--r--source/blender/draw/intern/draw_manager_exec.c5
-rw-r--r--source/blender/editors/object/object_bake_api.c18
-rw-r--r--source/blender/editors/render/render_preview.c9
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp12
-rw-r--r--source/blender/gpu/GPU_material.h5
-rw-r--r--source/blender/gpu/intern/gpu_material.c114
-rw-r--r--source/blender/gpu/intern/gpu_material_library.h2
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl4
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl14
-rw-r--r--source/blender/makesdna/DNA_layer_types.h2
-rw-r--r--source/blender/makesdna/DNA_node_types.h12
-rw-r--r--source/blender/makesdna/DNA_scene_defaults.h2
-rw-r--r--source/blender/makesdna/DNA_scene_types.h19
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c39
-rw-r--r--source/blender/makesrna/intern/rna_render.c98
-rw-r--r--source/blender/makesrna/intern/rna_scene.c63
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_image.c45
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c29
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c30
-rw-r--r--source/blender/render/CMakeLists.txt1
-rw-r--r--source/blender/render/RE_engine.h46
-rw-r--r--source/blender/render/RE_pipeline.h3
-rw-r--r--source/blender/render/intern/bake.c19
-rw-r--r--source/blender/render/intern/engine.c282
-rw-r--r--source/blender/render/intern/initrender.c91
-rw-r--r--source/blender/render/intern/initrender.h38
-rw-r--r--source/blender/render/intern/pipeline.c64
-rw-r--r--source/blender/render/intern/render_result.c253
-rw-r--r--source/blender/render/intern/render_result.h18
-rw-r--r--source/blender/render/intern/render_types.h30
-rw-r--r--source/blender/windowmanager/intern/wm_window.c13
51 files changed, 770 insertions, 1019 deletions
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index b3ee2f411d7..1f25106404a 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -39,7 +39,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
-#define BLENDER_FILE_SUBVERSION 24
+#define BLENDER_FILE_SUBVERSION 25
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index b489675cd74..434a2296d95 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -183,7 +183,6 @@ static ViewLayer *view_layer_add(const char *name)
view_layer->passflag = SCE_PASS_COMBINED;
view_layer->pass_alpha_threshold = 0.5f;
view_layer->cryptomatte_levels = 6;
- view_layer->cryptomatte_flag = VIEW_LAYER_CRYPTOMATTE_ACCURATE;
BKE_freestyle_config_init(&view_layer->freestyle_config);
return view_layer;
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index fa15e541e43..54d1efab7dd 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -651,13 +651,6 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain)
mat->line_col[3] = mat->alpha;
}
}
-
- if (!DNA_struct_elem_find(fd->filesdna, "RenderData", "int", "preview_start_resolution")) {
- Scene *scene;
- for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
- scene->r.preview_start_resolution = 64;
- }
- }
}
if (!MAIN_VERSION_ATLEAST(bmain, 271, 3)) {
@@ -698,15 +691,6 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
- if (!MAIN_VERSION_ATLEAST(bmain, 272, 0)) {
- if (!DNA_struct_elem_find(fd->filesdna, "RenderData", "int", "preview_start_resolution")) {
- Scene *scene;
- for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
- scene->r.preview_start_resolution = 64;
- }
- }
- }
-
if (!MAIN_VERSION_ATLEAST(bmain, 272, 1)) {
Brush *br;
for (br = bmain->brushes.first; br; br = br->id.next) {
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 9f2c090c242..69b67460a5d 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -3718,7 +3718,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
STRNCPY(node->idname, "ShaderNodeOutputLight");
}
if (node->type == SH_NODE_BSDF_PRINCIPLED && node->custom2 == 0) {
- node->custom2 = SHD_SUBSURFACE_BURLEY;
+ node->custom2 = SHD_SUBSURFACE_DIFFUSION;
}
}
}
diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c
index bafba486c88..be8c4b735be 100644
--- a/source/blender/blenloader/intern/versioning_290.c
+++ b/source/blender/blenloader/intern/versioning_290.c
@@ -1461,7 +1461,6 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
view_layer->cryptomatte_levels = 6;
- view_layer->cryptomatte_flag = VIEW_LAYER_CRYPTOMATTE_ACCURATE;
}
}
}
diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c
index 1a19bbbee5c..4dc6a0ecea6 100644
--- a/source/blender/blenloader/intern/versioning_300.c
+++ b/source/blender/blenloader/intern/versioning_300.c
@@ -784,6 +784,20 @@ static bool seq_transform_origin_set(Sequence *seq, void *UNUSED(user_data))
return true;
}
+static void do_version_subsurface_methods(bNode *node)
+{
+ if (node->type == SH_NODE_SUBSURFACE_SCATTERING) {
+ if (node->custom1 != SHD_SUBSURFACE_RANDOM_WALK) {
+ node->custom1 = SHD_SUBSURFACE_RANDOM_WALK_FIXED_RADIUS;
+ }
+ }
+ else if (node->type == SH_NODE_BSDF_PRINCIPLED) {
+ if (node->custom2 != SHD_SUBSURFACE_RANDOM_WALK) {
+ node->custom2 = SHD_SUBSURFACE_RANDOM_WALK_FIXED_RADIUS;
+ }
+ }
+}
+
/* NOLINTNEXTLINE: readability-function-size */
void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
{
@@ -1336,6 +1350,25 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
+ if (!MAIN_VERSION_ATLEAST(bmain, 300, 25)) {
+ FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
+ if (ntree->type == NTREE_SHADER) {
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ do_version_subsurface_methods(node);
+ }
+ }
+ }
+ FOREACH_NODETREE_END;
+
+ enum {
+ R_EXR_TILE_FILE = (1 << 10),
+ R_FULL_SAMPLE = (1 << 15),
+ };
+ LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
+ scene->r.scemode &= ~(R_EXR_TILE_FILE | R_FULL_SAMPLE);
+ }
+ }
+
/**
* Versioning code until next subversion bump goes here.
*
diff --git a/source/blender/blenloader/intern/versioning_cycles.c b/source/blender/blenloader/intern/versioning_cycles.c
index 90e6b43f02e..da57f27af4e 100644
--- a/source/blender/blenloader/intern/versioning_cycles.c
+++ b/source/blender/blenloader/intern/versioning_cycles.c
@@ -182,8 +182,8 @@ static void displacement_principled_nodes(bNode *node)
}
}
else if (node->type == SH_NODE_BSDF_PRINCIPLED) {
- if (node->custom2 != SHD_SUBSURFACE_RANDOM_WALK) {
- node->custom2 = SHD_SUBSURFACE_BURLEY;
+ if (node->custom2 != SHD_SUBSURFACE_RANDOM_WALK_FIXED_RADIUS) {
+ node->custom2 = SHD_SUBSURFACE_DIFFUSION;
}
}
}
@@ -1373,6 +1373,11 @@ void blo_do_versions_cycles(FileData *UNUSED(fd), Library *UNUSED(lib), Main *bm
void do_versions_after_linking_cycles(Main *bmain)
{
+ const int DENOISER_AUTO = 0;
+ const int DENOISER_NLM = 1;
+ const int DENOISER_OPTIX = 2;
+ const int DENOISER_OPENIMAGEDENOISE = 4;
+
if (!MAIN_VERSION_ATLEAST(bmain, 280, 66)) {
/* Shader node tree changes. After lib linking so we have all the typeinfo
* pointers and updated sockets and we can use the high level node API to
@@ -1578,10 +1583,6 @@ void do_versions_after_linking_cycles(Main *bmain)
}
if (cscene) {
- const int DENOISER_AUTO = 0;
- const int DENOISER_NLM = 1;
- const int DENOISER_OPTIX = 2;
-
/* Enable denoiser if it was enabled for one view layer before. */
cycles_property_int_set(cscene, "denoiser", (use_optix) ? DENOISER_OPTIX : DENOISER_NLM);
cycles_property_boolean_set(cscene, "use_denoising", use_denoising);
@@ -1637,4 +1638,17 @@ void do_versions_after_linking_cycles(Main *bmain)
object->visibility_flag |= flag;
}
}
+
+ if (!MAIN_VERSION_ATLEAST(bmain, 300, 25)) {
+ /* Removal of NLM denoiser. */
+ for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
+ IDProperty *cscene = cycles_properties_from_ID(&scene->id);
+
+ if (cscene) {
+ if (cycles_property_int(cscene, "denoiser", DENOISER_NLM) == DENOISER_NLM) {
+ cycles_property_int_set(cscene, "denoiser", DENOISER_OPENIMAGEDENOISE);
+ }
+ }
+ }
+ }
}
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c
index f2d5896be03..152ef79a38f 100644
--- a/source/blender/blenloader/intern/versioning_defaults.c
+++ b/source/blender/blenloader/intern/versioning_defaults.c
@@ -54,6 +54,7 @@
#include "BKE_curveprofile.h"
#include "BKE_customdata.h"
#include "BKE_gpencil.h"
+#include "BKE_idprop.h"
#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
@@ -356,6 +357,12 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
if (ts->custom_bevel_profile_preset == NULL) {
ts->custom_bevel_profile_preset = BKE_curveprofile_add(PROF_PRESET_LINE);
}
+
+ /* Clear ID properties so Cycles gets defaults. */
+ IDProperty *idprop = IDP_GetProperties(&scene->id, false);
+ if (idprop) {
+ IDP_ClearProperty(idprop);
+ }
}
/**
@@ -582,6 +589,10 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
bNodeSocket *roughness_socket = nodeFindSocket(node, SOCK_IN, "Roughness");
bNodeSocketValueFloat *roughness_data = roughness_socket->default_value;
roughness_data->value = 0.4f;
+ node->custom2 = SHD_SUBSURFACE_RANDOM_WALK;
+ }
+ else if (node->type == SH_NODE_SUBSURFACE_SCATTERING) {
+ node->custom1 = SHD_SUBSURFACE_RANDOM_WALK;
}
}
}
diff --git a/source/blender/compositor/nodes/COM_IDMaskNode.cc b/source/blender/compositor/nodes/COM_IDMaskNode.cc
index b51e79f2dea..761cb8b98cf 100644
--- a/source/blender/compositor/nodes/COM_IDMaskNode.cc
+++ b/source/blender/compositor/nodes/COM_IDMaskNode.cc
@@ -28,7 +28,7 @@ IDMaskNode::IDMaskNode(bNode *editorNode) : Node(editorNode)
/* pass */
}
void IDMaskNode::convertToOperations(NodeConverter &converter,
- const CompositorContext &context) const
+ const CompositorContext & /*context*/) const
{
bNode *bnode = this->getbNode();
@@ -38,7 +38,7 @@ void IDMaskNode::convertToOperations(NodeConverter &converter,
converter.addOperation(operation);
converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
- if (bnode->custom2 == 0 || context.getRenderData()->scemode & R_FULL_SAMPLE) {
+ if (bnode->custom2 == 0) {
converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
}
else {
diff --git a/source/blender/compositor/nodes/COM_ZCombineNode.cc b/source/blender/compositor/nodes/COM_ZCombineNode.cc
index ddf66740578..e29748dc317 100644
--- a/source/blender/compositor/nodes/COM_ZCombineNode.cc
+++ b/source/blender/compositor/nodes/COM_ZCombineNode.cc
@@ -31,9 +31,9 @@
namespace blender::compositor {
void ZCombineNode::convertToOperations(NodeConverter &converter,
- const CompositorContext &context) const
+ const CompositorContext & /*context*/) const
{
- if ((context.getRenderData()->scemode & R_FULL_SAMPLE) || this->getbNode()->custom2) {
+ if (this->getbNode()->custom2) {
ZCombineOperation *operation = nullptr;
if (this->getbNode()->custom1) {
operation = new ZCombineAlphaOperation();
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index a125a13eaf9..2e25211ea62 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -176,6 +176,9 @@ void DRW_deferred_shader_remove(struct GPUMaterial *mat);
struct DrawDataList *DRW_drawdatalist_from_id(struct ID *id);
void DRW_drawdata_free(struct ID *id);
+bool DRW_opengl_context_release(void);
+void DRW_opengl_context_activate(bool test);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/draw/engines/eevee/eevee_cryptomatte.c b/source/blender/draw/engines/eevee/eevee_cryptomatte.c
index 76a1b561972..49780abc6f4 100644
--- a/source/blender/draw/engines/eevee/eevee_cryptomatte.c
+++ b/source/blender/draw/engines/eevee/eevee_cryptomatte.c
@@ -139,8 +139,6 @@ void EEVEE_cryptomatte_renderpasses_init(EEVEE_Data *vedata)
g_data->cryptomatte_session = session;
g_data->render_passes |= EEVEE_RENDER_PASS_CRYPTOMATTE | EEVEE_RENDER_PASS_VOLUME_LIGHT;
- g_data->cryptomatte_accurate_mode = (view_layer->cryptomatte_flag &
- VIEW_LAYER_CRYPTOMATTE_ACCURATE) != 0;
}
}
@@ -405,7 +403,6 @@ void EEVEE_cryptomatte_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EE
{
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_StorageList *stl = vedata->stl;
- EEVEE_PrivateData *g_data = stl->g_data;
EEVEE_EffectsInfo *effects = stl->effects;
EEVEE_PassList *psl = vedata->psl;
const DRWContextState *draw_ctx = DRW_context_state_get();
@@ -413,10 +410,9 @@ void EEVEE_cryptomatte_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EE
const int cryptomatte_levels = view_layer->cryptomatte_levels;
const int current_sample = effects->taa_current_sample;
- /* In accurate mode all render samples are evaluated. In inaccurate mode this is limited to the
- * number of cryptomatte levels. This will reduce the overhead of downloading the GPU buffer and
- * integrating it into the accum buffer. */
- if (g_data->cryptomatte_accurate_mode || current_sample < cryptomatte_levels) {
+ /* Render samples used by cryptomatte are limited to the number of cryptomatte levels. This will
+ * reduce the overhead of downloading the GPU buffer and integrating it into the accum buffer. */
+ if (current_sample < cryptomatte_levels) {
static float clear_color[4] = {0.0};
GPU_framebuffer_bind(fbl->cryptomatte_fb);
GPU_framebuffer_clear_color(fbl->cryptomatte_fb, clear_color);
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 6a66e8b1a58..f8e1cc9c923 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -648,6 +648,8 @@ RenderEngineType DRW_engine_viewport_eevee_type = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
&EEVEE_render_update_passes,
&draw_engine_eevee_type,
{NULL, NULL, NULL},
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index f51b4fa0127..eae5d161cc3 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -1042,7 +1042,6 @@ typedef struct EEVEE_PrivateData {
int aov_hash;
int num_aovs_used;
struct CryptomatteSession *cryptomatte_session;
- bool cryptomatte_accurate_mode;
EEVEE_CryptomatteSample *cryptomatte_accum_buffer;
float *cryptomatte_download_buffer;
diff --git a/source/blender/draw/engines/external/external_engine.c b/source/blender/draw/engines/external/external_engine.c
index 89ee3f1b293..cc548a53a8e 100644
--- a/source/blender/draw/engines/external/external_engine.c
+++ b/source/blender/draw/engines/external/external_engine.c
@@ -32,13 +32,19 @@
#include "BKE_object.h"
#include "BKE_particle.h"
+#include "ED_image.h"
#include "ED_screen.h"
+#include "GPU_batch.h"
+#include "GPU_debug.h"
#include "GPU_matrix.h"
#include "GPU_shader.h"
#include "GPU_state.h"
#include "GPU_viewport.h"
+#include "RE_engine.h"
+#include "RE_pipeline.h"
+
#include "external_engine.h" /* own include */
/* Shaders */
@@ -137,6 +143,22 @@ static void external_engine_init(void *vedata)
}
}
+/* Add shading group call which will take care of writing to the depth buffer, so that the
+ * alpha-under overlay will happen for the render buffer. */
+static void external_cache_image_add(DRWShadingGroup *grp)
+{
+ float obmat[4][4];
+ unit_m4(obmat);
+ scale_m4_fl(obmat, 0.5f);
+
+ /* NOTE: Use the same Z-depth value as in the regular image drawing engine. */
+ translate_m4(obmat, 1.0f, 1.0f, 0.75f);
+
+ GPUBatch *geom = DRW_cache_quad_get();
+
+ DRW_shgroup_call_obmat(grp, geom, obmat);
+}
+
static void external_cache_init(void *vedata)
{
EXTERNAL_PassList *psl = ((EXTERNAL_Data *)vedata)->psl;
@@ -162,14 +184,33 @@ static void external_cache_init(void *vedata)
stl->g_data->depth_shgrp = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass);
}
- /* Do not draw depth pass when overlays are turned off. */
- stl->g_data->need_depth = (v3d->flag2 & V3D_HIDE_OVERLAYS) == 0;
+ if (v3d != NULL) {
+ /* Do not draw depth pass when overlays are turned off. */
+ stl->g_data->need_depth = (v3d->flag2 & V3D_HIDE_OVERLAYS) == 0;
+ }
+ else if (draw_ctx->space_data != NULL) {
+ const eSpace_Type space_type = draw_ctx->space_data->spacetype;
+ if (space_type == SPACE_IMAGE) {
+ external_cache_image_add(stl->g_data->depth_shgrp);
+
+ stl->g_data->need_depth = true;
+ stl->g_data->update_depth = true;
+ }
+ }
}
static void external_cache_populate(void *vedata, Object *ob)
{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
EXTERNAL_StorageList *stl = ((EXTERNAL_Data *)vedata)->stl;
+ if (draw_ctx->space_data != NULL) {
+ const eSpace_Type space_type = draw_ctx->space_data->spacetype;
+ if (space_type == SPACE_IMAGE) {
+ return;
+ }
+ }
+
if (!(DRW_object_is_renderable(ob) &&
DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF)) {
return;
@@ -210,13 +251,11 @@ static void external_cache_finish(void *UNUSED(vedata))
{
}
-static void external_draw_scene_do(void *vedata)
+static void external_draw_scene_do_v3d(void *vedata)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
- Scene *scene = draw_ctx->scene;
RegionView3D *rv3d = draw_ctx->rv3d;
ARegion *region = draw_ctx->region;
- const RenderEngineType *type;
DRW_state_reset_ex(DRW_STATE_DEFAULT & ~DRW_STATE_DEPTH_LESS_EQUAL);
@@ -229,8 +268,6 @@ static void external_draw_scene_do(void *vedata)
}
RenderEngine *engine = RE_engine_create(engine_type);
- engine->tile_x = scene->r.tilex;
- engine->tile_y = scene->r.tiley;
engine_type->view_update(engine, draw_ctx->evil_C, draw_ctx->depsgraph);
rv3d->render_engine = engine;
}
@@ -241,7 +278,7 @@ static void external_draw_scene_do(void *vedata)
ED_region_pixelspace(region);
/* Render result draw. */
- type = rv3d->render_engine->type;
+ const RenderEngineType *type = rv3d->render_engine->type;
type->view_draw(rv3d->render_engine, draw_ctx->evil_C, draw_ctx->depsgraph);
GPU_bgl_end();
@@ -259,6 +296,116 @@ static void external_draw_scene_do(void *vedata)
}
}
+/* Configure current matrix stack so that the external engine can use the same drawing code for
+ * both viewport and image editor drawing.
+ *
+ * The engine draws result in the pixel space, and is applying render offset. For image editor we
+ * need to switch from normalized space to pixel space, and "un-apply" offset. */
+static void external_image_space_matrix_set(const RenderEngine *engine)
+{
+ BLI_assert(engine != NULL);
+
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const DRWView *view = DRW_view_get_active();
+ struct SpaceImage *space_image = (struct SpaceImage *)draw_ctx->space_data;
+
+ /* Apply current view as transformation matrix.
+ * This will configure drawing for normalized space with current zoom and pan applied. */
+
+ float view_matrix[4][4];
+ DRW_view_viewmat_get(view, view_matrix, false);
+
+ float projection_matrix[4][4];
+ DRW_view_winmat_get(view, projection_matrix, false);
+
+ GPU_matrix_projection_set(projection_matrix);
+ GPU_matrix_set(view_matrix);
+
+ /* Switch from normalized space to pixel space. */
+ {
+ int width, height;
+ ED_space_image_get_size(space_image, &width, &height);
+
+ const float width_inv = width ? 1.0f / width : 0.0f;
+ const float height_inv = height ? 1.0f / height : 0.0f;
+ GPU_matrix_scale_2f(width_inv, height_inv);
+ }
+
+ /* Un-apply render offset. */
+ {
+ Render *render = engine->re;
+ rctf view_rect;
+ rcti render_rect;
+ RE_GetViewPlane(render, &view_rect, &render_rect);
+
+ GPU_matrix_translate_2f(-render_rect.xmin, -render_rect.ymin);
+ }
+}
+
+static void external_draw_scene_do_image(void *UNUSED(vedata))
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ Render *re = RE_GetSceneRender(scene);
+ RenderEngine *engine = RE_engine_get(re);
+
+ /* Is tested before enabling the drawing engine. */
+ BLI_assert(re != NULL);
+ BLI_assert(engine != NULL);
+
+ const DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+
+ /* Clear the depth buffer to the value used by the background overlay so that the overlay is not
+ * happening outside of the drawn image.
+ *
+ * NOTE: The external engine only draws color. The depth is taken care of using the depth pass
+ * which initialized the depth to the values expected by the background overlay. */
+ GPU_framebuffer_clear_depth(dfbl->default_fb, 1.0f);
+
+ GPU_matrix_push_projection();
+ GPU_matrix_push();
+
+ external_image_space_matrix_set(engine);
+
+ GPU_debug_group_begin("External Engine");
+
+ const RenderEngineType *engine_type = engine->type;
+ BLI_assert(engine_type != NULL);
+ BLI_assert(engine_type->draw != NULL);
+
+ engine_type->draw(engine, draw_ctx->evil_C, draw_ctx->depsgraph);
+
+ GPU_debug_group_end();
+
+ GPU_matrix_pop();
+ GPU_matrix_pop_projection();
+
+ DRW_state_reset();
+ GPU_bgl_end();
+
+ RE_engine_draw_release(re);
+}
+
+static void external_draw_scene_do(void *vedata)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+
+ if (draw_ctx->v3d != NULL) {
+ external_draw_scene_do_v3d(vedata);
+ return;
+ }
+
+ if (draw_ctx->space_data == NULL) {
+ return;
+ }
+
+ const eSpace_Type space_type = draw_ctx->space_data->spacetype;
+ if (space_type == SPACE_IMAGE) {
+ external_draw_scene_do_image(vedata);
+ return;
+ }
+}
+
static void external_draw_scene(void *vedata)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
@@ -297,7 +444,7 @@ static void external_engine_free(void)
static const DrawEngineDataSize external_data_size = DRW_VIEWPORT_DATA_SIZE(EXTERNAL_Data);
-static DrawEngineType draw_engine_external_type = {
+DrawEngineType draw_engine_external_type = {
NULL,
NULL,
N_("External"),
@@ -330,8 +477,45 @@ RenderEngineType DRW_engine_viewport_external_type = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
&draw_engine_external_type,
{NULL, NULL, NULL},
};
+bool DRW_engine_external_acquire_for_image_editor(void)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const SpaceLink *space_data = draw_ctx->space_data;
+ Scene *scene = draw_ctx->scene;
+
+ if (space_data == NULL) {
+ return false;
+ }
+
+ const eSpace_Type space_type = draw_ctx->space_data->spacetype;
+ if (space_type != SPACE_IMAGE) {
+ return false;
+ }
+
+ struct SpaceImage *space_image = (struct SpaceImage *)space_data;
+ const Image *image = ED_space_image(space_image);
+ if (image == NULL || image->type != IMA_TYPE_R_RESULT) {
+ return false;
+ }
+
+ if (image->render_slot != image->last_render_slot) {
+ return false;
+ }
+
+ /* Render is allocated on main thread, so it is safe to access it from here. */
+ Render *re = RE_GetSceneRender(scene);
+
+ if (re == NULL) {
+ return false;
+ }
+
+ return RE_engine_draw_acquire(re);
+}
+
#undef EXTERNAL_ENGINE
diff --git a/source/blender/draw/engines/external/external_engine.h b/source/blender/draw/engines/external/external_engine.h
index c645fb99e0e..14ec4e2d3c5 100644
--- a/source/blender/draw/engines/external/external_engine.h
+++ b/source/blender/draw/engines/external/external_engine.h
@@ -22,4 +22,12 @@
#pragma once
+extern DrawEngineType draw_engine_external_type;
extern RenderEngineType DRW_engine_viewport_external_type;
+
+/* Check whether an external engine is to be used to draw content of an image editor.
+ * If the drawing is possible, the render engine is "acquired" so that it is not freed by the
+ * render engine for until drawing is finished.
+ *
+ * NOTE: Released by the draw engine when it is done drawing. */
+bool DRW_engine_external_acquire_for_image_editor(void);
diff --git a/source/blender/draw/engines/select/select_engine.c b/source/blender/draw/engines/select/select_engine.c
index 96ab8a28e09..20edd78597b 100644
--- a/source/blender/draw/engines/select/select_engine.c
+++ b/source/blender/draw/engines/select/select_engine.c
@@ -388,6 +388,8 @@ RenderEngineType DRW_engine_viewport_select_type = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
&draw_engine_select_type,
{NULL, NULL, NULL},
};
diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c
index f09c019ef8d..635aa7cef25 100644
--- a/source/blender/draw/engines/workbench/workbench_engine.c
+++ b/source/blender/draw/engines/workbench/workbench_engine.c
@@ -651,6 +651,8 @@ RenderEngineType DRW_engine_viewport_workbench_type = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
&workbench_render_update_passes,
&draw_engine_workbench,
{NULL, NULL, NULL},
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 660a4adaf51..fb8b8536897 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -623,6 +623,7 @@ const DRWView *DRW_view_default_get(void);
void DRW_view_default_set(DRWView *view);
void DRW_view_reset(void);
void DRW_view_set_active(DRWView *view);
+const DRWView *DRW_view_get_active(void);
void DRW_view_clip_planes_set(DRWView *view, float (*planes)[4], int plane_len);
void DRW_view_camtexco_set(DRWView *view, float texco[4]);
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 47adc0acc60..e65fdce5f2e 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -1197,6 +1197,18 @@ static void drw_engines_enable_basic(void)
use_drw_engine(&draw_engine_basic_type);
}
+static void drw_engine_enable_image_editor(void)
+{
+ if (DRW_engine_external_acquire_for_image_editor()) {
+ use_drw_engine(&draw_engine_external_type);
+ }
+ else {
+ use_drw_engine(&draw_engine_image_type);
+ }
+
+ use_drw_engine(&draw_engine_overlay_type);
+}
+
static void drw_engines_enable_editors(void)
{
SpaceLink *space_data = DST.draw_ctx.space_data;
@@ -1205,8 +1217,7 @@ static void drw_engines_enable_editors(void)
}
if (space_data->spacetype == SPACE_IMAGE) {
- use_drw_engine(&draw_engine_image_type);
- use_drw_engine(&draw_engine_overlay_type);
+ drw_engine_enable_image_editor();
}
else if (space_data->spacetype == SPACE_NODE) {
/* Only enable when drawing the space image backdrop. */
@@ -3188,3 +3199,66 @@ void DRW_draw_state_init_gtests(eGPUShaderConfig sh_cfg)
#endif
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Draw manager context release/activation
+ *
+ * These functions are used in cases when an OpenGL context creation is needed during the draw.
+ * This happens, for example, when an external engine needs to create its own OpenGL context from
+ * the engine initialization.
+ *
+ * Example of context creation:
+ *
+ * const bool drw_state = DRW_opengl_context_release();
+ * gl_context = WM_opengl_context_create();
+ * DRW_opengl_context_activate(drw_state);
+ *
+ * Example of context destruction:
+ *
+ * const bool drw_state = DRW_opengl_context_release();
+ * WM_opengl_context_activate(gl_context);
+ * WM_opengl_context_dispose(gl_context);
+ * DRW_opengl_context_activate(drw_state);
+ *
+ *
+ * NOTE: Will only perform context modification when on main thread. This way these functions can
+ * be used in an engine without check on whether it is a draw manager which manages OpenGL context
+ * on the current thread. The downside of this is that if the engine performs OpenGL creation from
+ * a non-main thread, that thread is supposed to not have OpenGL context ever bound by Blender.
+ *
+ * \{ */
+
+bool DRW_opengl_context_release(void)
+{
+ if (!BLI_thread_is_main()) {
+ return false;
+ }
+
+ if (GPU_context_active_get() != DST.gpu_context) {
+ /* Context release is requested from the outside of the draw manager main draw loop, indicate
+ * this to the `DRW_opengl_context_activate()` so that it restores drawable of the window. */
+ return false;
+ }
+
+ GPU_context_active_set(NULL);
+ WM_opengl_context_release(DST.gl_context);
+
+ return true;
+}
+
+void DRW_opengl_context_activate(bool drw_state)
+{
+ if (!BLI_thread_is_main()) {
+ return;
+ }
+
+ if (drw_state) {
+ WM_opengl_context_activate(DST.gl_context);
+ GPU_context_active_set(DST.gpu_context);
+ }
+ else {
+ wm_window_reset_drawable();
+ }
+}
+
+/** \} */
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index 22356a3c57b..aa01ca7a262 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -367,6 +367,11 @@ void DRW_view_set_active(DRWView *view)
DST.view_active = (view) ? view : DST.view_default;
}
+const DRWView *DRW_view_get_active(void)
+{
+ return DST.view_active;
+}
+
/* Return True if the given BoundSphere intersect the current view frustum */
static bool draw_culling_sphere_test(const BoundSphere *frustum_bsphere,
const float (*frustum_planes)[4],
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index 0a2df655395..26f5b21a311 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -412,6 +412,7 @@ static bool is_noncolor_pass(eScenePassType pass_type)
{
return ELEM(pass_type,
SCE_PASS_Z,
+ SCE_PASS_POSITION,
SCE_PASS_NORMAL,
SCE_PASS_VECTOR,
SCE_PASS_INDEXOB,
@@ -554,19 +555,10 @@ static bool bake_pass_filter_check(eScenePassType pass_type,
return true;
}
- if ((pass_filter & R_BAKE_PASS_FILTER_AO) != 0) {
- BKE_report(
- reports,
- RPT_ERROR,
- "Combined bake pass Ambient Occlusion contribution requires an enabled light pass "
- "(bake the Ambient Occlusion pass type instead)");
- }
- else {
- BKE_report(reports,
- RPT_ERROR,
- "Combined bake pass requires Emit, or a light pass with "
- "Direct or Indirect contributions enabled");
- }
+ BKE_report(reports,
+ RPT_ERROR,
+ "Combined bake pass requires Emit, or a light pass with "
+ "Direct or Indirect contributions enabled");
return false;
}
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 95351de45f0..81aecfdf788 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -479,15 +479,6 @@ static Scene *preview_prepare_scene(
BKE_color_managed_view_settings_free(&sce->view_settings);
BKE_color_managed_view_settings_copy(&sce->view_settings, &scene->view_settings);
- /* prevent overhead for small renders and icons (32) */
- if (id && sp->sizex < 40) {
- sce->r.tilex = sce->r.tiley = 64;
- }
- else {
- sce->r.tilex = sce->r.xsch / 4;
- sce->r.tiley = sce->r.ysch / 4;
- }
-
if ((id && sp->pr_method == PR_ICON_RENDER) && id_type != ID_WO) {
sce->r.alphamode = R_ALPHAPREMUL;
}
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
index 937a10f26b1..0a82c237256 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
@@ -94,17 +94,15 @@ BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count)
freestyle_scene = BKE_scene_add(freestyle_bmain, name);
freestyle_scene->r.cfra = old_scene->r.cfra;
freestyle_scene->r.mode = old_scene->r.mode & ~(R_EDGE_FRS | R_BORDER);
- freestyle_scene->r.xsch = re->rectx; // old_scene->r.xsch
- freestyle_scene->r.ysch = re->recty; // old_scene->r.ysch
- freestyle_scene->r.xasp = 1.0f; // old_scene->r.xasp;
- freestyle_scene->r.yasp = 1.0f; // old_scene->r.yasp;
- freestyle_scene->r.tilex = old_scene->r.tilex;
- freestyle_scene->r.tiley = old_scene->r.tiley;
+ freestyle_scene->r.xsch = re->rectx; // old_scene->r.xsch
+ freestyle_scene->r.ysch = re->recty; // old_scene->r.ysch
+ freestyle_scene->r.xasp = 1.0f; // old_scene->r.xasp;
+ freestyle_scene->r.yasp = 1.0f; // old_scene->r.yasp;
freestyle_scene->r.size = 100; // old_scene->r.size
freestyle_scene->r.color_mgt_flag = 0; // old_scene->r.color_mgt_flag;
freestyle_scene->r.scemode = (old_scene->r.scemode &
~(R_SINGLE_LAYER | R_NO_FRAME_UPDATE | R_MULTIVIEW)) &
- (re->r.scemode | ~R_FULL_SAMPLE);
+ (re->r.scemode);
freestyle_scene->r.flag = old_scene->r.flag;
freestyle_scene->r.threads = old_scene->r.threads;
freestyle_scene->r.border.xmin = old_scene->r.border.xmin;
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index 312da491a36..e64521768f9 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -175,10 +175,7 @@ GPUNodeLink *GPU_uniformbuf_link_out(struct GPUMaterial *mat,
void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link);
void GPU_material_add_output_link_aov(GPUMaterial *material, GPUNodeLink *link, int hash);
-void GPU_material_sss_profile_create(GPUMaterial *material,
- float radii[3],
- const short *falloff_type,
- const float *sharpness);
+void GPU_material_sss_profile_create(GPUMaterial *material, float radii[3]);
struct GPUUniformBuf *GPU_material_sss_profile_get(GPUMaterial *material,
int sample_len,
struct GPUTexture **tex_profile);
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 56e72fbeca9..6872a08e854 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -96,8 +96,6 @@ struct GPUMaterial {
float sss_enabled;
float sss_radii[3];
int sss_samples;
- short int sss_falloff;
- float sss_sharpness;
bool sss_dirty;
GPUTexture *coba_tex; /* 1D Texture array containing all color bands. */
@@ -266,18 +264,6 @@ static void sss_calculate_offsets(GPUSssKernelData *kd, int count, float exponen
}
}
-#define GAUSS_TRUNCATE 12.46f
-static float gaussian_profile(float r, float radius)
-{
- const float v = radius * radius * (0.25f * 0.25f);
- const float Rm = sqrtf(v * GAUSS_TRUNCATE);
-
- if (r >= Rm) {
- return 0.0f;
- }
- return expf(-r * r / (2.0f * v)) / (2.0f * M_PI * v);
-}
-
#define BURLEY_TRUNCATE 16.0f
#define BURLEY_TRUNCATE_CDF 0.9963790093708328f // cdf(BURLEY_TRUNCATE)
static float burley_profile(float r, float d)
@@ -287,45 +273,15 @@ static float burley_profile(float r, float d)
return (exp_r_d + exp_r_3_d) / (4.0f * d);
}
-static float cubic_profile(float r, float radius, float sharpness)
-{
- float Rm = radius * (1.0f + sharpness);
-
- if (r >= Rm) {
- return 0.0f;
- }
- /* custom variation with extra sharpness, to match the previous code */
- const float y = 1.0f / (1.0f + sharpness);
- float Rmy, ry, ryinv;
-
- Rmy = powf(Rm, y);
- ry = powf(r, y);
- ryinv = (r > 0.0f) ? powf(r, y - 1.0f) : 0.0f;
-
- const float Rmy5 = (Rmy * Rmy) * (Rmy * Rmy) * Rmy;
- const float f = Rmy - ry;
- const float num = f * (f * f) * (y * ryinv);
-
- return (10.0f * num) / (Rmy5 * M_PI);
-}
-
-static float eval_profile(float r, short falloff_type, float sharpness, float param)
+static float eval_profile(float r, float param)
{
r = fabsf(r);
-
- if (ELEM(falloff_type, SHD_SUBSURFACE_BURLEY, SHD_SUBSURFACE_RANDOM_WALK)) {
- return burley_profile(r, param) / BURLEY_TRUNCATE_CDF;
- }
- if (falloff_type == SHD_SUBSURFACE_CUBIC) {
- return cubic_profile(r, param, sharpness);
- }
-
- return gaussian_profile(r, param);
+ return burley_profile(r, param) / BURLEY_TRUNCATE_CDF;
}
/* Resolution for each sample of the precomputed kernel profile */
#define INTEGRAL_RESOLUTION 32
-static float eval_integral(float x0, float x1, short falloff_type, float sharpness, float param)
+static float eval_integral(float x0, float x1, float param)
{
const float range = x1 - x0;
const float step = range / INTEGRAL_RESOLUTION;
@@ -333,7 +289,7 @@ static float eval_integral(float x0, float x1, short falloff_type, float sharpne
for (int i = 0; i < INTEGRAL_RESOLUTION; i++) {
float x = x0 + range * ((float)i + 0.5f) / (float)INTEGRAL_RESOLUTION;
- float y = eval_profile(x, falloff_type, sharpness, param);
+ float y = eval_profile(x, param);
integral += y * step;
}
@@ -341,8 +297,7 @@ static float eval_integral(float x0, float x1, short falloff_type, float sharpne
}
#undef INTEGRAL_RESOLUTION
-static void compute_sss_kernel(
- GPUSssKernelData *kd, const float radii[3], int sample_len, int falloff_type, float sharpness)
+static void compute_sss_kernel(GPUSssKernelData *kd, const float radii[3], int sample_len)
{
float rad[3];
/* Minimum radius */
@@ -353,27 +308,15 @@ static void compute_sss_kernel(
/* Christensen-Burley fitting */
float l[3], d[3];
- if (ELEM(falloff_type, SHD_SUBSURFACE_BURLEY, SHD_SUBSURFACE_RANDOM_WALK)) {
- mul_v3_v3fl(l, rad, 0.25f * M_1_PI);
- const float A = 1.0f;
- const float s = 1.9f - A + 3.5f * (A - 0.8f) * (A - 0.8f);
- /* XXX 0.6f Out of nowhere to match cycles! Empirical! Can be tweak better. */
- mul_v3_v3fl(d, l, 0.6f / s);
- mul_v3_v3fl(rad, d, BURLEY_TRUNCATE);
- kd->max_radius = MAX3(rad[0], rad[1], rad[2]);
-
- copy_v3_v3(kd->param, d);
- }
- else if (falloff_type == SHD_SUBSURFACE_CUBIC) {
- copy_v3_v3(kd->param, rad);
- mul_v3_fl(rad, 1.0f + sharpness);
- kd->max_radius = MAX3(rad[0], rad[1], rad[2]);
- }
- else {
- kd->max_radius = MAX3(rad[0], rad[1], rad[2]);
+ mul_v3_v3fl(l, rad, 0.25f * M_1_PI);
+ const float A = 1.0f;
+ const float s = 1.9f - A + 3.5f * (A - 0.8f) * (A - 0.8f);
+ /* XXX 0.6f Out of nowhere to match cycles! Empirical! Can be tweak better. */
+ mul_v3_v3fl(d, l, 0.6f / s);
+ mul_v3_v3fl(rad, d, BURLEY_TRUNCATE);
+ kd->max_radius = MAX3(rad[0], rad[1], rad[2]);
- copy_v3_v3(kd->param, rad);
- }
+ copy_v3_v3(kd->param, d);
/* Compute samples locations on the 1d kernel [-1..1] */
sss_calculate_offsets(kd, sample_len, SSS_EXPONENT);
@@ -403,9 +346,9 @@ static void compute_sss_kernel(
x0 *= kd->max_radius;
x1 *= kd->max_radius;
- kd->kernel[i][0] = eval_integral(x0, x1, falloff_type, sharpness, kd->param[0]);
- kd->kernel[i][1] = eval_integral(x0, x1, falloff_type, sharpness, kd->param[1]);
- kd->kernel[i][2] = eval_integral(x0, x1, falloff_type, sharpness, kd->param[2]);
+ kd->kernel[i][0] = eval_integral(x0, x1, kd->param[0]);
+ kd->kernel[i][1] = eval_integral(x0, x1, kd->param[1]);
+ kd->kernel[i][2] = eval_integral(x0, x1, kd->param[2]);
sum[0] += kd->kernel[i][0];
sum[1] += kd->kernel[i][1];
@@ -439,8 +382,6 @@ static void compute_sss_kernel(
#define INTEGRAL_RESOLUTION 512
static void compute_sss_translucence_kernel(const GPUSssKernelData *kd,
int resolution,
- short falloff_type,
- float sharpness,
float **output)
{
float(*texels)[4];
@@ -463,9 +404,9 @@ static void compute_sss_translucence_kernel(const GPUSssKernelData *kd,
float dist = hypotf(r + r_step * 0.5f, d);
float profile[3];
- profile[0] = eval_profile(dist, falloff_type, sharpness, kd->param[0]);
- profile[1] = eval_profile(dist, falloff_type, sharpness, kd->param[1]);
- profile[2] = eval_profile(dist, falloff_type, sharpness, kd->param[2]);
+ profile[0] = eval_profile(dist, kd->param[0]);
+ profile[1] = eval_profile(dist, kd->param[1]);
+ profile[2] = eval_profile(dist, kd->param[2]);
/* Since the profile and configuration are radially symmetrical we
* can just evaluate it once and weight it accordingly */
@@ -499,14 +440,9 @@ static void compute_sss_translucence_kernel(const GPUSssKernelData *kd,
}
#undef INTEGRAL_RESOLUTION
-void GPU_material_sss_profile_create(GPUMaterial *material,
- float radii[3],
- const short *falloff_type,
- const float *sharpness)
+void GPU_material_sss_profile_create(GPUMaterial *material, float radii[3])
{
copy_v3_v3(material->sss_radii, radii);
- material->sss_falloff = (falloff_type) ? *falloff_type : 0.0;
- material->sss_sharpness = (sharpness) ? *sharpness : 0.0;
material->sss_dirty = true;
material->sss_enabled = true;
@@ -527,20 +463,14 @@ struct GPUUniformBuf *GPU_material_sss_profile_get(GPUMaterial *material,
if (material->sss_dirty || (material->sss_samples != sample_len)) {
GPUSssKernelData kd;
- float sharpness = material->sss_sharpness;
-
- /* XXX Black magic but it seems to fit. Maybe because we integrate -1..1 */
- sharpness *= 0.5f;
-
- compute_sss_kernel(&kd, material->sss_radii, sample_len, material->sss_falloff, sharpness);
+ compute_sss_kernel(&kd, material->sss_radii, sample_len);
/* Update / Create UBO */
GPU_uniformbuf_update(material->sss_profile, &kd);
/* Update / Create Tex */
float *translucence_profile;
- compute_sss_translucence_kernel(
- &kd, 64, material->sss_falloff, sharpness, &translucence_profile);
+ compute_sss_translucence_kernel(&kd, 64, &translucence_profile);
if (material->sss_tex_profile != NULL) {
GPU_texture_free(material->sss_tex_profile);
diff --git a/source/blender/gpu/intern/gpu_material_library.h b/source/blender/gpu/intern/gpu_material_library.h
index 782d89d6f2a..d3b12d3a2b7 100644
--- a/source/blender/gpu/intern/gpu_material_library.h
+++ b/source/blender/gpu/intern/gpu_material_library.h
@@ -27,7 +27,7 @@
#include "GPU_material.h"
#define MAX_FUNCTION_NAME 64
-#define MAX_PARAMETER 32
+#define MAX_PARAMETER 36
struct GSet;
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl
index d77259638fd..bba84c2be52 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl
@@ -19,6 +19,8 @@ void node_bsdf_principled(vec4 base_color,
float subsurface,
vec3 subsurface_radius,
vec4 subsurface_color,
+ float subsurface_ior,
+ float subsurface_anisotropy,
float metallic,
float specular,
float specular_tint,
@@ -201,6 +203,6 @@ void node_bsdf_principled(vec4 base_color,
#else
/* clang-format off */
/* Stub principled because it is not compatible with volumetrics. */
-# define node_bsdf_principled(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, bb, cc, dd, result) (result = CLOSURE_DEFAULT)
+# define node_bsdf_principled(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, bb, cc, dd, ee, ff, result) (result = CLOSURE_DEFAULT)
/* clang-format on */
#endif
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl
index 5129bf71903..d0c159cdf37 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl
@@ -5,8 +5,8 @@ CLOSURE_EVAL_FUNCTION_DECLARE_1(node_subsurface_scattering, Diffuse)
void node_subsurface_scattering(vec4 color,
float scale,
vec3 radius,
- float sharpen,
- float texture_blur,
+ float ior,
+ float anisotropy,
vec3 N,
float sss_id,
out Closure result)
@@ -20,15 +20,7 @@ void node_subsurface_scattering(vec4 color,
result = CLOSURE_DEFAULT;
- /* Not perfect for texture_blur values between 0.0 and 1.0.
- * Interpolate between separated color and color applied on irradiance. */
- float one_minus_texture_blur = 1.0 - texture_blur;
- vec3 sss_albedo = color.rgb * one_minus_texture_blur + texture_blur;
- vec3 radiance_tint = color.rgb * texture_blur + one_minus_texture_blur;
- /* Consider output radiance as irradiance. */
- out_Diffuse_0.radiance *= radiance_tint;
-
- closure_load_sss_data(scale, out_Diffuse_0.radiance, sss_albedo, int(sss_id), result);
+ closure_load_sss_data(scale, out_Diffuse_0.radiance, color.rgb, int(sss_id), result);
/* TODO(fclem) Try to not use this. */
closure_load_ssr_data(vec3(0.0), 0.0, in_Diffuse_0.N, -1.0, result);
diff --git a/source/blender/makesdna/DNA_layer_types.h b/source/blender/makesdna/DNA_layer_types.h
index 63e4597150c..520f989452c 100644
--- a/source/blender/makesdna/DNA_layer_types.h
+++ b/source/blender/makesdna/DNA_layer_types.h
@@ -68,7 +68,7 @@ typedef enum eViewLayerCryptomatteFlags {
VIEW_LAYER_CRYPTOMATTE_OBJECT = (1 << 0),
VIEW_LAYER_CRYPTOMATTE_MATERIAL = (1 << 1),
VIEW_LAYER_CRYPTOMATTE_ASSET = (1 << 2),
- VIEW_LAYER_CRYPTOMATTE_ACCURATE = (1 << 3),
+ /* VIEW_LAYER_CRYPTOMATTE_ACCURATE = (1 << 3), */ /* DEPRECATED */
} eViewLayerCryptomatteFlags;
#define VIEW_LAYER_CRYPTOMATTE_ALL \
(VIEW_LAYER_CRYPTOMATTE_OBJECT | VIEW_LAYER_CRYPTOMATTE_MATERIAL | VIEW_LAYER_CRYPTOMATTE_ASSET)
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 49083542fd7..cf159a1e28d 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -1032,6 +1032,11 @@ typedef struct NodeShaderTexPointDensity {
char _pad2[4];
} NodeShaderTexPointDensity;
+typedef struct NodeShaderPrincipled {
+ char use_subsurface_auto_radius;
+ char _pad[3];
+} NodeShaderPrincipled;
+
/* TEX_output */
typedef struct TexNodeOutput {
char name[64];
@@ -1803,11 +1808,12 @@ enum {
enum {
#ifdef DNA_DEPRECATED_ALLOW
SHD_SUBSURFACE_COMPATIBLE = 0, /* Deprecated */
-#endif
SHD_SUBSURFACE_CUBIC = 1,
SHD_SUBSURFACE_GAUSSIAN = 2,
- SHD_SUBSURFACE_BURLEY = 3,
- SHD_SUBSURFACE_RANDOM_WALK = 4,
+#endif
+ SHD_SUBSURFACE_DIFFUSION = 3,
+ SHD_SUBSURFACE_RANDOM_WALK_FIXED_RADIUS = 4,
+ SHD_SUBSURFACE_RANDOM_WALK = 5,
};
/* blur node */
diff --git a/source/blender/makesdna/DNA_scene_defaults.h b/source/blender/makesdna/DNA_scene_defaults.h
index 61707964191..9ecf94ebd6e 100644
--- a/source/blender/makesdna/DNA_scene_defaults.h
+++ b/source/blender/makesdna/DNA_scene_defaults.h
@@ -135,8 +135,6 @@
.border.xmax = 1.0f, \
.border.ymax = 1.0f, \
\
- .preview_start_resolution = 64, \
- \
.line_thickness_mode = R_LINE_THICKNESS_ABSOLUTE, \
.unit_line_thickness = 1.0f, \
\
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index f2244b4ae61..b28c3ac2b85 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -261,7 +261,7 @@ typedef enum eScenePassType {
SCE_PASS_UNUSED_3 = (1 << 4), /* SPEC */
SCE_PASS_SHADOW = (1 << 5),
SCE_PASS_AO = (1 << 6),
- SCE_PASS_UNUSED_4 = (1 << 7), /* REFLECT */
+ SCE_PASS_POSITION = (1 << 7),
SCE_PASS_NORMAL = (1 << 8),
SCE_PASS_VECTOR = (1 << 9),
SCE_PASS_UNUSED_5 = (1 << 10), /* REFRACT */
@@ -293,6 +293,7 @@ typedef enum eScenePassType {
#define RE_PASSNAME_COMBINED "Combined"
#define RE_PASSNAME_Z "Depth"
#define RE_PASSNAME_VECTOR "Vector"
+#define RE_PASSNAME_POSITION "Position"
#define RE_PASSNAME_NORMAL "Normal"
#define RE_PASSNAME_UV "UV"
#define RE_PASSNAME_EMIT "Emit"
@@ -592,7 +593,7 @@ typedef enum eBakeSaveMode {
/** #BakeData.pass_filter */
typedef enum eBakePassFilter {
R_BAKE_PASS_FILTER_NONE = 0,
- R_BAKE_PASS_FILTER_AO = (1 << 0),
+ R_BAKE_PASS_FILTER_UNUSED = (1 << 0),
R_BAKE_PASS_FILTER_EMIT = (1 << 1),
R_BAKE_PASS_FILTER_DIFFUSE = (1 << 2),
R_BAKE_PASS_FILTER_GLOSSY = (1 << 3),
@@ -653,7 +654,8 @@ typedef struct RenderData {
/**
* render tile dimensions
*/
- int tilex, tiley;
+ int tilex DNA_DEPRECATED;
+ int tiley DNA_DEPRECATED;
short planes DNA_DEPRECATED;
short imtype DNA_DEPRECATED;
@@ -764,13 +766,10 @@ typedef struct RenderData {
/* Cycles baking */
struct BakeData bake;
- int preview_start_resolution;
+ int _pad8;
short preview_pixel_size;
- /* Type of the debug pass to use.
- * Only used when built with debug passes support.
- */
- short debug_pass_type;
+ short _pad4;
/* MultiView */
/** SceneRenderView. */
@@ -1887,12 +1886,12 @@ enum {
#define R_COMP_CROP (1 << 7)
#define R_SCEMODE_UNUSED_8 (1 << 8) /* cleared */
#define R_SINGLE_LAYER (1 << 9)
-#define R_EXR_TILE_FILE (1 << 10)
+#define R_SCEMODE_UNUSED_10 (1 << 10) /* cleared */
#define R_SCEMODE_UNUSED_11 (1 << 11) /* cleared */
#define R_NO_IMAGE_LOAD (1 << 12)
#define R_SCEMODE_UNUSED_13 (1 << 13) /* cleared */
#define R_NO_FRAME_UPDATE (1 << 14)
-#define R_FULL_SAMPLE (1 << 15)
+#define R_SCEMODE_UNUSED_15 (1 << 15) /* cleared */
#define R_SCEMODE_UNUSED_16 (1 << 16) /* cleared */
#define R_SCEMODE_UNUSED_17 (1 << 17) /* cleared */
#define R_TEXNODE_PREVIEW (1 << 18)
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index d0bf60d5d02..ec53f35df4c 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -4665,16 +4665,18 @@ static const EnumPropertyItem node_principled_distribution_items[] = {
};
static const EnumPropertyItem node_subsurface_method_items[] = {
- {SHD_SUBSURFACE_BURLEY,
- "BURLEY",
+ {SHD_SUBSURFACE_RANDOM_WALK_FIXED_RADIUS,
+ "RANDOM_WALK_FIXED_RADIUS",
0,
- "Christensen-Burley",
- "Approximation to physically based volume scattering"},
+ "Random Walk (Fixed Radius)",
+ "Volumetric approximation to physically based volume scattering, using the scattering radius "
+ "as specified"},
{SHD_SUBSURFACE_RANDOM_WALK,
"RANDOM_WALK",
0,
"Random Walk",
- "Volumetric approximation to physically based volume scattering"},
+ "Volumetric approximation to physically based volume scattering, with scattering radius "
+ "automatically adjusted to match color textures"},
{0, NULL, 0, NULL, NULL}};
/* -- Common nodes ---------------------------------------------------------- */
@@ -6144,35 +6146,12 @@ static void def_sh_ambient_occlusion(StructRNA *srna)
static void def_sh_subsurface(StructRNA *srna)
{
- static const EnumPropertyItem prop_subsurface_falloff_items[] = {
- {SHD_SUBSURFACE_CUBIC, "CUBIC", 0, "Cubic", "Simple cubic falloff function"},
- {SHD_SUBSURFACE_GAUSSIAN,
- "GAUSSIAN",
- 0,
- "Gaussian",
- "Normal distribution, multiple can be combined to fit more complex profiles"},
- {SHD_SUBSURFACE_BURLEY,
- "BURLEY",
- 0,
- "Christensen-Burley",
- "Approximation to physically based volume scattering"},
- {SHD_SUBSURFACE_RANDOM_WALK,
- "RANDOM_WALK",
- 0,
- "Random Walk",
- "Volumetric approximation to physically based volume scattering"},
- {0, NULL, 0, NULL, NULL},
- };
-
PropertyRNA *prop;
prop = RNA_def_property(srna, "falloff", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
- RNA_def_property_enum_items(prop, prop_subsurface_falloff_items);
- RNA_def_property_ui_text(prop,
- "Falloff",
- "Function to determine how much light nearby points contribute based "
- "on their distance to the shading point");
+ RNA_def_property_enum_items(prop, node_subsurface_method_items);
+ RNA_def_property_ui_text(prop, "Method", "Method for rendering subsurface scattering");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNode_socket_update");
}
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index 4400d198b4a..fcb46904e8d 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -52,6 +52,7 @@ const EnumPropertyItem rna_enum_render_pass_type_items[] = {
{SCE_PASS_Z, "Z", 0, "Z", ""},
{SCE_PASS_SHADOW, "SHADOW", 0, "Shadow", ""},
{SCE_PASS_AO, "AO", 0, "Ambient Occlusion", ""},
+ {SCE_PASS_POSITION, "POSITION", 0, "Position", ""},
{SCE_PASS_NORMAL, "NORMAL", 0, "Normal", ""},
{SCE_PASS_VECTOR, "VECTOR", 0, "Vector", ""},
{SCE_PASS_INDEXOB, "OBJECT_INDEX", 0, "Object Index", ""},
@@ -79,6 +80,7 @@ const EnumPropertyItem rna_enum_bake_pass_type_items[] = {
{SCE_PASS_COMBINED, "COMBINED", 0, "Combined", ""},
{SCE_PASS_AO, "AO", 0, "Ambient Occlusion", ""},
{SCE_PASS_SHADOW, "SHADOW", 0, "Shadow", ""},
+ {SCE_PASS_POSITION, "POSITION", 0, "Position", ""},
{SCE_PASS_NORMAL, "NORMAL", 0, "Normal", ""},
{SCE_PASS_UV, "UV", 0, "UV", ""},
{SCE_PASS_ROUGHNESS, "ROUGHNESS", 0, "ROUGHNESS", ""},
@@ -177,6 +179,40 @@ static void engine_render(RenderEngine *engine, Depsgraph *depsgraph)
RNA_parameter_list_free(&list);
}
+static void engine_render_frame_finish(RenderEngine *engine)
+{
+ extern FunctionRNA rna_RenderEngine_render_frame_finish_func;
+ PointerRNA ptr;
+ ParameterList list;
+ FunctionRNA *func;
+
+ RNA_pointer_create(NULL, engine->type->rna_ext.srna, engine, &ptr);
+ func = &rna_RenderEngine_render_frame_finish_func;
+
+ RNA_parameter_list_create(&list, &ptr, func);
+ engine->type->rna_ext.call(NULL, &ptr, func, &list);
+
+ RNA_parameter_list_free(&list);
+}
+
+static void engine_draw(RenderEngine *engine, const struct bContext *context, Depsgraph *depsgraph)
+{
+ extern FunctionRNA rna_RenderEngine_draw_func;
+ PointerRNA ptr;
+ ParameterList list;
+ FunctionRNA *func;
+
+ RNA_pointer_create(NULL, engine->type->rna_ext.srna, engine, &ptr);
+ func = &rna_RenderEngine_draw_func;
+
+ RNA_parameter_list_create(&list, &ptr, func);
+ RNA_parameter_set_lookup(&list, "context", &context);
+ RNA_parameter_set_lookup(&list, "depsgraph", &depsgraph);
+ engine->type->rna_ext.call(NULL, &ptr, func, &list);
+
+ RNA_parameter_list_free(&list);
+}
+
static void engine_bake(RenderEngine *engine,
struct Depsgraph *depsgraph,
struct Object *object,
@@ -315,7 +351,7 @@ static StructRNA *rna_RenderEngine_register(Main *bmain,
RenderEngineType *et, dummyet = {NULL};
RenderEngine dummyengine = {NULL};
PointerRNA dummyptr;
- int have_function[8];
+ int have_function[9];
/* setup dummy engine & engine type to store static properties in */
dummyengine.type = &dummyet;
@@ -358,11 +394,13 @@ static StructRNA *rna_RenderEngine_register(Main *bmain,
et->update = (have_function[0]) ? engine_update : NULL;
et->render = (have_function[1]) ? engine_render : NULL;
- et->bake = (have_function[2]) ? engine_bake : NULL;
- et->view_update = (have_function[3]) ? engine_view_update : NULL;
- et->view_draw = (have_function[4]) ? engine_view_draw : NULL;
- et->update_script_node = (have_function[5]) ? engine_update_script_node : NULL;
- et->update_render_passes = (have_function[6]) ? engine_update_render_passes : NULL;
+ et->render_frame_finish = (have_function[2]) ? engine_render_frame_finish : NULL;
+ et->draw = (have_function[3]) ? engine_draw : NULL;
+ et->bake = (have_function[4]) ? engine_bake : NULL;
+ et->view_update = (have_function[5]) ? engine_view_update : NULL;
+ et->view_draw = (have_function[6]) ? engine_view_draw : NULL;
+ et->update_script_node = (have_function[7]) ? engine_update_script_node : NULL;
+ et->update_render_passes = (have_function[8]) ? engine_update_render_passes : NULL;
RE_engines_register(et);
@@ -519,6 +557,19 @@ static void rna_def_render_engine(BlenderRNA *brna)
parm = RNA_def_pointer(func, "depsgraph", "Depsgraph", "", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ func = RNA_def_function(srna, "render_frame_finish", NULL);
+ RNA_def_function_ui_description(
+ func, "Perform finishing operations after all view layers in a frame were rendered");
+ RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
+
+ func = RNA_def_function(srna, "draw", NULL);
+ RNA_def_function_ui_description(func, "Draw render image");
+ RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
+ parm = RNA_def_pointer(func, "context", "Context", "", "");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ parm = RNA_def_pointer(func, "depsgraph", "Depsgraph", "", "");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+
func = RNA_def_function(srna, "bake", NULL);
RNA_def_function_ui_description(func, "Bake passes");
RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
@@ -641,6 +692,14 @@ static void rna_def_render_engine(BlenderRNA *brna)
parm = RNA_def_boolean(func, "do_break", 0, "Break", "");
RNA_def_function_return(func, parm);
+ func = RNA_def_function(srna, "pass_by_index_get", "RE_engine_pass_by_index_get");
+ parm = RNA_def_string(func, "layer", NULL, 0, "Layer", "Name of render layer to get pass for");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ parm = RNA_def_int(func, "index", 0, 0, INT_MAX, "Index", "Index of pass to get", 0, INT_MAX);
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ parm = RNA_def_pointer(func, "render_pass", "RenderPass", "Index", "Index of pass to get");
+ RNA_def_function_return(func, parm);
+
func = RNA_def_function(srna, "active_view_get", "RE_engine_active_view_get");
parm = RNA_def_string(func, "view", NULL, 0, "View", "Single view active");
RNA_def_function_return(func, parm);
@@ -761,6 +820,22 @@ static void rna_def_render_engine(BlenderRNA *brna)
func = RNA_def_function(srna, "free_blender_memory", "RE_engine_free_blender_memory");
RNA_def_function_ui_description(func, "Free Blender side memory of render engine");
+ func = RNA_def_function(srna, "tile_highlight_set", "RE_engine_tile_highlight_set");
+ RNA_def_function_ui_description(func, "Set highlighted state of the given tile");
+ parm = RNA_def_int(func, "x", 0, 0, INT_MAX, "X", "", 0, INT_MAX);
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ parm = RNA_def_int(func, "y", 0, 0, INT_MAX, "Y", "", 0, INT_MAX);
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ parm = RNA_def_int(func, "width", 0, 0, INT_MAX, "Width", "", 0, INT_MAX);
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ parm = RNA_def_int(func, "height", 0, 0, INT_MAX, "Height", "", 0, INT_MAX);
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ parm = RNA_def_boolean(func, "highlight", 0, "Highlight", "");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+
+ func = RNA_def_function(srna, "tile_highlight_clear_all", "RE_engine_tile_highlight_clear_all");
+ RNA_def_function_ui_description(func, "Clear highlight from all tiles");
+
RNA_define_verify_sdna(0);
prop = RNA_def_property(srna, "is_animation", PROP_BOOLEAN, PROP_NONE);
@@ -777,11 +852,6 @@ static void rna_def_render_engine(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "layer_override", 1);
RNA_def_property_array(prop, 20);
- prop = RNA_def_property(srna, "tile_x", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_int_sdna(prop, NULL, "tile_x");
- prop = RNA_def_property(srna, "tile_y", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_int_sdna(prop, NULL, "tile_y");
-
prop = RNA_def_property(srna, "resolution_x", PROP_INT, PROP_PIXEL);
RNA_def_property_int_sdna(prop, NULL, "resolution_x");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -880,12 +950,6 @@ static void rna_def_render_engine(BlenderRNA *brna)
"Don't expose Cycles and Eevee shading nodes in the node editor user "
"interface, so own nodes can be used instead");
- prop = RNA_def_property(srna, "bl_use_save_buffers", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "type->flag", RE_USE_SAVE_BUFFERS);
- RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
- RNA_def_property_ui_text(
- prop, "Use Save Buffers", "Support render to an on disk buffer during rendering");
-
prop = RNA_def_property(srna, "bl_use_spherical_stereo", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "type->flag", RE_USE_SPHERICAL_STEREO);
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 1762b964f8d..e45d39a1ddc 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -532,7 +532,6 @@ const EnumPropertyItem rna_enum_stereo3d_interlace_type_items[] = {
const EnumPropertyItem rna_enum_bake_pass_filter_type_items[] = {
{R_BAKE_PASS_FILTER_NONE, "NONE", 0, "None", ""},
- {R_BAKE_PASS_FILTER_AO, "AO", 0, "Ambient Occlusion", ""},
{R_BAKE_PASS_FILTER_EMIT, "EMIT", 0, "Emit", ""},
{R_BAKE_PASS_FILTER_DIRECT, "DIRECT", 0, "Direct", ""},
{R_BAKE_PASS_FILTER_INDIRECT, "INDIRECT", 0, "Indirect", ""},
@@ -4151,13 +4150,6 @@ void rna_def_view_layer_common(BlenderRNA *brna, StructRNA *srna, const bool sce
prop, "Cryptomatte Levels", "Sets how many unique objects can be distinguished per pixel");
RNA_def_property_ui_range(prop, 2.0, 16.0, 2.0, 0.0);
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
-
- prop = RNA_def_property(srna, "use_pass_cryptomatte_accurate", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "cryptomatte_flag", VIEW_LAYER_CRYPTOMATTE_ACCURATE);
- RNA_def_property_boolean_default(prop, true);
- RNA_def_property_ui_text(
- prop, "Cryptomatte Accurate", "Generate a more accurate cryptomatte pass");
- RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
}
prop = RNA_def_property(srna, "use_solid", PROP_BOOLEAN, PROP_NONE);
@@ -4251,6 +4243,16 @@ void rna_def_view_layer_common(BlenderRNA *brna, StructRNA *srna, const bool sce
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
}
+ prop = RNA_def_property(srna, "use_pass_position", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_POSITION);
+ RNA_def_property_ui_text(prop, "Position", "Deliver position pass");
+ if (scene) {
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
+ }
+ else {
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ }
+
prop = RNA_def_property(srna, "use_pass_normal", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_NORMAL);
RNA_def_property_ui_text(prop, "Normal", "Deliver normal pass");
@@ -5122,10 +5124,6 @@ static void rna_def_bake_data(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
/* custom passes flags */
- prop = RNA_def_property(srna, "use_pass_ambient_occlusion", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "pass_filter", R_BAKE_PASS_FILTER_AO);
- RNA_def_property_ui_text(prop, "Ambient Occlusion", "Add ambient occlusion contribution");
-
prop = RNA_def_property(srna, "use_pass_emit", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "pass_filter", R_BAKE_PASS_FILTER_EMIT);
RNA_def_property_ui_text(prop, "Emit", "Add emission contribution");
@@ -5934,29 +5932,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Resolution %", "Percentage scale for render resolution");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_SceneSequencer_update");
- prop = RNA_def_property(srna, "tile_x", PROP_INT, PROP_PIXEL);
- RNA_def_property_int_sdna(prop, NULL, "tilex");
- RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_range(prop, 8, 65536);
- RNA_def_property_ui_text(prop, "Tile X", "Horizontal tile size to use while rendering");
- RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
- prop = RNA_def_property(srna, "tile_y", PROP_INT, PROP_PIXEL);
- RNA_def_property_int_sdna(prop, NULL, "tiley");
- RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_range(prop, 8, 65536);
- RNA_def_property_ui_text(prop, "Tile Y", "Vertical tile size to use while rendering");
- RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
- prop = RNA_def_property(srna, "preview_start_resolution", PROP_INT, PROP_NONE);
- RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_range(prop, 8, 16384);
- RNA_def_property_ui_text(prop,
- "Start Resolution",
- "Resolution to start rendering preview at, "
- "progressively increasing it to the full viewport size");
- RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
prop = RNA_def_property(srna, "preview_pixel_size", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "preview_pixel_size");
RNA_def_property_enum_items(prop, pixel_size_items);
@@ -6213,24 +6188,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Movie Format", "When true the format is a movie");
- prop = RNA_def_property(srna, "use_save_buffers", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_EXR_TILE_FILE);
- RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(
- prop,
- "Save Buffers",
- "Save tiles for all RenderLayers and SceneNodes to files in the temp directory "
- "(saves memory, required for Full Sample)");
- RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
- prop = RNA_def_property(srna, "use_full_sample", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_FULL_SAMPLE);
- RNA_def_property_ui_text(prop,
- "Full Sample",
- "Save for every anti-aliasing sample the entire RenderLayer results "
- "(this solves anti-aliasing issues with compositing)");
- RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
prop = RNA_def_property(srna, "use_lock_interface", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "use_lock_interface", 1);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c
index 243300b0a44..a56dfea9dbf 100644
--- a/source/blender/nodes/composite/nodes/node_composite_image.c
+++ b/source/blender/nodes/composite/nodes/node_composite_image.c
@@ -45,7 +45,7 @@ static bNodeSocketTemplate cmp_node_rlayers_out[] = {
{SOCK_VECTOR, N_(RE_PASSNAME_NORMAL), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{SOCK_VECTOR, N_(RE_PASSNAME_UV), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{SOCK_VECTOR, N_(RE_PASSNAME_VECTOR), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_RGBA, N_(RE_PASSNAME_DEPRECATED), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ {SOCK_VECTOR, N_(RE_PASSNAME_POSITION), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{SOCK_RGBA, N_(RE_PASSNAME_DEPRECATED), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{SOCK_RGBA, N_(RE_PASSNAME_DEPRECATED), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{SOCK_RGBA, N_(RE_PASSNAME_SHADOW), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
@@ -72,7 +72,7 @@ static bNodeSocketTemplate cmp_node_rlayers_out[] = {
{SOCK_RGBA, N_(RE_PASSNAME_SUBSURFACE_COLOR), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{-1, ""},
};
-#define MAX_LEGACY_SOCKET_INDEX 30
+#define NUM_LEGACY_SOCKETS (ARRAY_SIZE(cmp_node_rlayers_out) - 1)
static void cmp_node_image_add_pass_output(bNodeTree *ntree,
bNode *node,
@@ -382,7 +382,7 @@ static void cmp_node_image_verify_outputs(bNodeTree *ntree, bNode *node, bool rl
break;
}
}
- if (!link && (!rlayer || sock_index > MAX_LEGACY_SOCKET_INDEX)) {
+ if (!link && (!rlayer || sock_index >= NUM_LEGACY_SOCKETS)) {
MEM_freeN(sock->storage);
nodeRemoveSocket(ntree, node, sock);
}
@@ -468,43 +468,12 @@ void node_cmp_rlayers_outputs(bNodeTree *ntree, bNode *node)
const char *node_cmp_rlayers_sock_to_pass(int sock_index)
{
- const char *sock_to_passname[] = {
- RE_PASSNAME_COMBINED,
- RE_PASSNAME_COMBINED,
- RE_PASSNAME_Z,
- RE_PASSNAME_NORMAL,
- RE_PASSNAME_UV,
- RE_PASSNAME_VECTOR,
- RE_PASSNAME_DEPRECATED,
- RE_PASSNAME_DEPRECATED,
- RE_PASSNAME_DEPRECATED,
- RE_PASSNAME_SHADOW,
- RE_PASSNAME_AO,
- RE_PASSNAME_DEPRECATED,
- RE_PASSNAME_DEPRECATED,
- RE_PASSNAME_DEPRECATED,
- RE_PASSNAME_INDEXOB,
- RE_PASSNAME_INDEXMA,
- RE_PASSNAME_MIST,
- RE_PASSNAME_EMIT,
- RE_PASSNAME_ENVIRONMENT,
- RE_PASSNAME_DIFFUSE_DIRECT,
- RE_PASSNAME_DIFFUSE_INDIRECT,
- RE_PASSNAME_DIFFUSE_COLOR,
- RE_PASSNAME_GLOSSY_DIRECT,
- RE_PASSNAME_GLOSSY_INDIRECT,
- RE_PASSNAME_GLOSSY_COLOR,
- RE_PASSNAME_TRANSM_DIRECT,
- RE_PASSNAME_TRANSM_INDIRECT,
- RE_PASSNAME_TRANSM_COLOR,
- RE_PASSNAME_SUBSURFACE_DIRECT,
- RE_PASSNAME_SUBSURFACE_INDIRECT,
- RE_PASSNAME_SUBSURFACE_COLOR,
- };
- if (sock_index > MAX_LEGACY_SOCKET_INDEX) {
+ if (sock_index >= NUM_LEGACY_SOCKETS) {
return NULL;
}
- return sock_to_passname[sock_index];
+ const char *name = cmp_node_rlayers_out[sock_index].name;
+ /* Exception for alpha, which is derived from Combined. */
+ return (STREQ(name, "Alpha")) ? RE_PASSNAME_COMBINED : name;
}
static void node_composit_init_rlayers(const bContext *C, PointerRNA *ptr)
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c
index f601f3e9fd0..06f4d1f1b79 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c
@@ -35,6 +35,8 @@ static bNodeSocketTemplate sh_node_bsdf_principled_in[] = {
PROP_NONE,
SOCK_COMPACT},
{SOCK_RGBA, N_("Subsurface Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ {SOCK_FLOAT, N_("Subsurface IOR"), 1.4f, 0.0f, 0.0f, 0.0f, 1.01f, 3.8f, PROP_FACTOR},
+ {SOCK_FLOAT, N_("Subsurface Anisotropy"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{SOCK_FLOAT, N_("Metallic"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{SOCK_FLOAT, N_("Specular"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{SOCK_FLOAT, N_("Specular Tint"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
@@ -74,7 +76,7 @@ static bNodeSocketTemplate sh_node_bsdf_principled_out[] = {
static void node_shader_init_principled(bNodeTree *UNUSED(ntree), bNode *node)
{
node->custom1 = SHD_GLOSSY_GGX;
- node->custom2 = SHD_SUBSURFACE_BURLEY;
+ node->custom2 = SHD_SUBSURFACE_RANDOM_WALK;
}
#define socket_not_zero(sock) (in[sock].link || (clamp_f(in[sock].vec[0], 0.0f, 1.0f) > 1e-5f))
@@ -90,41 +92,40 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat,
GPUNodeLink *sss_scale;
/* Normals */
- if (!in[20].link) {
- GPU_link(mat, "world_normals_get", &in[20].link);
+ if (!in[22].link) {
+ GPU_link(mat, "world_normals_get", &in[22].link);
}
/* Clearcoat Normals */
- if (!in[21].link) {
- GPU_link(mat, "world_normals_get", &in[21].link);
+ if (!in[23].link) {
+ GPU_link(mat, "world_normals_get", &in[23].link);
}
#if 0 /* Not used at the moment. */
/* Tangents */
- if (!in[22].link) {
+ if (!in[24].link) {
GPUNodeLink *orco = GPU_attribute(CD_ORCO, "");
- GPU_link(mat, "tangent_orco_z", orco, &in[22].link);
+ GPU_link(mat, "tangent_orco_z", orco, &in[24].link);
GPU_link(mat,
"node_tangent",
GPU_builtin(GPU_WORLD_NORMAL),
- in[22].link,
+ in[24].link,
GPU_builtin(GPU_OBJECT_MATRIX),
- &in[22].link);
+ &in[24].link);
}
#endif
- bool use_diffuse = socket_not_one(4) && socket_not_one(15);
+ bool use_diffuse = socket_not_one(6) && socket_not_one(17);
bool use_subsurf = socket_not_zero(1) && use_diffuse && node->sss_id > 0;
- bool use_refract = socket_not_one(4) && socket_not_zero(15);
- bool use_clear = socket_not_zero(12);
+ bool use_refract = socket_not_one(6) && socket_not_zero(17);
+ bool use_clear = socket_not_zero(14);
/* SSS Profile */
if (use_subsurf) {
- static short profile = SHD_SUBSURFACE_BURLEY;
bNodeSocket *socket = BLI_findlink(&node->original->inputs, 2);
bNodeSocketValueRGBA *socket_data = socket->default_value;
/* For some reason it seems that the socket value is in ARGB format. */
- GPU_material_sss_profile_create(mat, &socket_data->value[1], &profile, NULL);
+ GPU_material_sss_profile_create(mat, &socket_data->value[1]);
}
if (in[2].link) {
diff --git a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c
index 4b91bcbd11c..e917858e0f2 100644
--- a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c
+++ b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c
@@ -25,8 +25,8 @@ static bNodeSocketTemplate sh_node_subsurface_scattering_in[] = {
{SOCK_RGBA, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
{SOCK_FLOAT, N_("Scale"), 1.0, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
{SOCK_VECTOR, N_("Radius"), 1.0f, 0.2f, 0.1f, 0.0f, 0.0f, 100.0f, PROP_NONE, SOCK_COMPACT},
- {SOCK_FLOAT, N_("Sharpness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- {SOCK_FLOAT, N_("Texture Blur"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ {SOCK_FLOAT, N_("IOR"), 1.4f, 0.0f, 0.0f, 0.0f, 1.01f, 3.8f, PROP_FACTOR},
+ {SOCK_FLOAT, N_("Anisotropy"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
{-1, ""},
};
@@ -38,7 +38,8 @@ static bNodeSocketTemplate sh_node_subsurface_scattering_out[] = {
static void node_shader_init_subsurface_scattering(bNodeTree *UNUSED(ntree), bNode *node)
{
- node->custom1 = SHD_SUBSURFACE_BURLEY;
+ node->custom1 = SHD_SUBSURFACE_RANDOM_WALK;
+ node->custom2 = true;
}
static int node_shader_gpu_subsurface_scattering(GPUMaterial *mat,
@@ -54,11 +55,8 @@ static int node_shader_gpu_subsurface_scattering(GPUMaterial *mat,
if (node->sss_id > 0) {
bNodeSocket *socket = BLI_findlink(&node->original->inputs, 2);
bNodeSocketValueRGBA *socket_data = socket->default_value;
- bNodeSocket *socket_sharp = BLI_findlink(&node->original->inputs, 3);
- bNodeSocketValueFloat *socket_data_sharp = socket_sharp->default_value;
/* For some reason it seems that the socket value is in ARGB format. */
- GPU_material_sss_profile_create(
- mat, &socket_data->value[1], &node->original->custom1, &socket_data_sharp->value);
+ GPU_material_sss_profile_create(mat, &socket_data->value[1]);
/* sss_id is 0 only the node is not connected to any output.
* In this case flagging the material would trigger a bug (see T68736). */
@@ -69,23 +67,6 @@ static int node_shader_gpu_subsurface_scattering(GPUMaterial *mat,
mat, node, "node_subsurface_scattering", in, out, GPU_constant(&node->sss_id));
}
-static void node_shader_update_subsurface_scattering(bNodeTree *UNUSED(ntree), bNode *node)
-{
- bNodeSocket *sock;
- int falloff = node->custom1;
-
- for (sock = node->inputs.first; sock; sock = sock->next) {
- if (STREQ(sock->name, "Sharpness")) {
- if (falloff == SHD_SUBSURFACE_CUBIC) {
- sock->flag &= ~SOCK_UNAVAIL;
- }
- else {
- sock->flag |= SOCK_UNAVAIL;
- }
- }
- }
-}
-
/* node type definition */
void register_node_type_sh_subsurface_scattering(void)
{
@@ -99,7 +80,6 @@ void register_node_type_sh_subsurface_scattering(void)
node_type_init(&ntype, node_shader_init_subsurface_scattering);
node_type_storage(&ntype, "", NULL, NULL);
node_type_gpu(&ntype, node_shader_gpu_subsurface_scattering);
- node_type_update(&ntype, node_shader_update_subsurface_scattering);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt
index 0046474d064..494415a4077 100644
--- a/source/blender/render/CMakeLists.txt
+++ b/source/blender/render/CMakeLists.txt
@@ -59,7 +59,6 @@ set(SRC
RE_pipeline.h
RE_texture.h
- intern/initrender.h
intern/pipeline.h
intern/render_result.h
intern/render_types.h
diff --git a/source/blender/render/RE_engine.h b/source/blender/render/RE_engine.h
index dfc0d5d0e9f..2a3a5964262 100644
--- a/source/blender/render/RE_engine.h
+++ b/source/blender/render/RE_engine.h
@@ -40,6 +40,7 @@ struct RenderData;
struct RenderEngine;
struct RenderEngineType;
struct RenderLayer;
+struct RenderPass;
struct RenderResult;
struct ReportList;
struct Scene;
@@ -59,7 +60,7 @@ extern "C" {
#define RE_USE_PREVIEW 4
#define RE_USE_POSTPROCESS 8
#define RE_USE_EEVEE_VIEWPORT 16
-#define RE_USE_SAVE_BUFFERS 32
+/* #define RE_USE_SAVE_BUFFERS_DEPRECATED 32 */
#define RE_USE_SHADING_NODES_CUSTOM 64
#define RE_USE_SPHERICAL_STEREO 128
#define RE_USE_STEREO_VIEWPORT 256
@@ -75,6 +76,7 @@ extern "C" {
#define RE_ENGINE_DO_UPDATE 8
#define RE_ENGINE_RENDERING 16
#define RE_ENGINE_HIGHLIGHT_TILES 32
+#define RE_ENGINE_CAN_DRAW 64
extern ListBase R_engines;
@@ -87,7 +89,20 @@ typedef struct RenderEngineType {
int flag;
void (*update)(struct RenderEngine *engine, struct Main *bmain, struct Depsgraph *depsgraph);
+
void (*render)(struct RenderEngine *engine, struct Depsgraph *depsgraph);
+
+ /* Offline rendering is finished - no more view layers will be rendered.
+ *
+ * All the pending data is to be communicated from the engine back to Blender. In a possibly
+ * most memory-efficient manner (engine might free its database before making Blender to allocate
+ * full-frame render result). */
+ void (*render_frame_finish)(struct RenderEngine *engine);
+
+ void (*draw)(struct RenderEngine *engine,
+ const struct bContext *context,
+ struct Depsgraph *depsgraph);
+
void (*bake)(struct RenderEngine *engine,
struct Depsgraph *depsgraph,
struct Object *object,
@@ -132,9 +147,6 @@ typedef struct RenderEngine {
struct Object *camera_override;
unsigned int layer_override;
- int tile_x;
- int tile_y;
-
struct Render *re;
ListBase fullresult;
char text[512]; /* IMA_MAX_RENDER_TEXT */
@@ -189,6 +201,10 @@ void RE_engine_end_result(RenderEngine *engine,
bool merge_results);
struct RenderResult *RE_engine_get_result(struct RenderEngine *engine);
+struct RenderPass *RE_engine_pass_by_index_get(struct RenderEngine *engine,
+ const char *layer_name,
+ int index);
+
const char *RE_engine_active_view_get(RenderEngine *engine);
void RE_engine_active_view_set(RenderEngine *engine, const char *viewname);
float RE_engine_get_camera_shift_x(RenderEngine *engine,
@@ -228,6 +244,24 @@ void RE_engine_register_pass(struct RenderEngine *engine,
bool RE_engine_use_persistent_data(struct RenderEngine *engine);
+struct RenderEngine *RE_engine_get(const struct Render *re);
+
+/* Acquire render engine for drawing via its `draw()` callback.
+ *
+ * If drawing is not possible false is returned. If drawing is possible then the engine is
+ * "acquired" so that it can not be freed by the render pipeline.
+ *
+ * Drawing is possible if the engine has the `draw()` callback and it is in its `render()`
+ * callback. */
+bool RE_engine_draw_acquire(struct Render *re);
+void RE_engine_draw_release(struct Render *re);
+
+/* NOTE: Only used for Cycles's BLenderGPUDisplay integration with the draw manager. A subject
+ * for re-consideration. Do not use this functionality. */
+bool RE_engine_has_render_context(struct RenderEngine *engine);
+void RE_engine_render_context_enable(struct RenderEngine *engine);
+void RE_engine_render_context_disable(struct RenderEngine *engine);
+
/* Engine Types */
void RE_engines_init(void);
@@ -252,6 +286,10 @@ void RE_bake_engine_set_engine_parameters(struct Render *re,
void RE_engine_free_blender_memory(struct RenderEngine *engine);
+void RE_engine_tile_highlight_set(
+ struct RenderEngine *engine, int x, int y, int width, int height, bool highlight);
+void RE_engine_tile_highlight_clear_all(struct RenderEngine *engine);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/render/RE_pipeline.h b/source/blender/render/RE_pipeline.h
index cd839385bfb..3237772dd80 100644
--- a/source/blender/render/RE_pipeline.h
+++ b/source/blender/render/RE_pipeline.h
@@ -141,9 +141,6 @@ typedef struct RenderResult {
volatile rcti renrect;
volatile RenderLayer *renlay;
- /* optional saved endresult on disk */
- int do_exr_tile;
-
/* for render results in Image, verify validity for sequences */
int framenr;
diff --git a/source/blender/render/intern/bake.c b/source/blender/render/intern/bake.c
index 76839651b5d..0f893ce8cd5 100644
--- a/source/blender/render/intern/bake.c
+++ b/source/blender/render/intern/bake.c
@@ -774,18 +774,6 @@ void RE_bake_pixels_populate(Mesh *me,
/* ******************** NORMALS ************************ */
-/**
- * convert a normalized normal to the -1.0 1.0 range
- * the input is expected to be POS_X, POS_Y, POS_Z
- */
-static void normal_uncompress(float out[3], const float in[3])
-{
- int i;
- for (i = 0; i < 3; i++) {
- out[i] = 2.0f * in[i] - 1.0f;
- }
-}
-
static void normal_compress(float out[3],
const float in[3],
const eBakeNormalSwizzle normal_swizzle[3])
@@ -934,7 +922,7 @@ void RE_bake_normal_world_to_tangent(const BakePixel pixel_array[],
copy_v3_v3(tsm[2], normal);
/* texture values */
- normal_uncompress(nor, &result[offset]);
+ copy_v3_v3(nor, &result[offset]);
/* converts from world space to local space */
mul_transposed_mat3_m4_v3(mat, nor);
@@ -976,7 +964,7 @@ void RE_bake_normal_world_to_object(const BakePixel pixel_array[],
}
offset = i * depth;
- normal_uncompress(nor, &result[offset]);
+ copy_v3_v3(nor, &result[offset]);
/* rotates only without translation */
mul_mat3_m4_v3(iobmat, nor);
@@ -1004,7 +992,7 @@ void RE_bake_normal_world_to_world(const BakePixel pixel_array[],
}
offset = i * depth;
- normal_uncompress(nor, &result[offset]);
+ copy_v3_v3(nor, &result[offset]);
/* save back the values */
normal_compress(&result[offset], nor, normal_swizzle);
@@ -1053,6 +1041,7 @@ int RE_pass_depth(const eScenePassType pass_type)
}
case SCE_PASS_COMBINED:
case SCE_PASS_SHADOW:
+ case SCE_PASS_POSITION:
case SCE_PASS_NORMAL:
case SCE_PASS_VECTOR:
case SCE_PASS_INDEXOB: /* XXX double check */
diff --git a/source/blender/render/intern/engine.c b/source/blender/render/intern/engine.c
index 5728b784714..389b821ca35 100644
--- a/source/blender/render/intern/engine.c
+++ b/source/blender/render/intern/engine.c
@@ -62,7 +62,6 @@
#include "DRW_engine.h"
-#include "initrender.h"
#include "pipeline.h"
#include "render_result.h"
#include "render_types.h"
@@ -283,14 +282,6 @@ static void render_result_to_bake(RenderEngine *engine, RenderResult *rr)
/* Render Results */
-static RenderPart *get_part_from_result(Render *re, RenderResult *result)
-{
- rcti key = result->tilerect;
- BLI_rcti_translate(&key, re->disprect.xmin, re->disprect.ymin);
-
- return BLI_ghash_lookup(re->parts, &key);
-}
-
static HighlightedTile highlighted_tile_from_result_get(Render *re, RenderResult *result)
{
HighlightedTile tile;
@@ -300,6 +291,37 @@ static HighlightedTile highlighted_tile_from_result_get(Render *re, RenderResult
return tile;
}
+static void engine_tile_highlight_set(RenderEngine *engine,
+ const HighlightedTile *tile,
+ bool highlight)
+{
+ if ((engine->flag & RE_ENGINE_HIGHLIGHT_TILES) == 0) {
+ return;
+ }
+
+ Render *re = engine->re;
+
+ BLI_mutex_lock(&re->highlighted_tiles_mutex);
+
+ if (re->highlighted_tiles == NULL) {
+ re->highlighted_tiles = BLI_gset_new(
+ BLI_ghashutil_inthash_v4_p, BLI_ghashutil_inthash_v4_cmp, "highlighted tiles");
+ }
+
+ if (highlight) {
+ HighlightedTile **tile_in_set;
+ if (!BLI_gset_ensure_p_ex(re->highlighted_tiles, tile, (void ***)&tile_in_set)) {
+ *tile_in_set = MEM_mallocN(sizeof(HighlightedTile), __func__);
+ **tile_in_set = *tile;
+ }
+ }
+ else {
+ BLI_gset_remove(re->highlighted_tiles, tile, MEM_freeN);
+ }
+
+ BLI_mutex_unlock(&re->highlighted_tiles_mutex);
+}
+
RenderResult *RE_engine_begin_result(
RenderEngine *engine, int x, int y, int w, int h, const char *layername, const char *viewname)
{
@@ -332,7 +354,7 @@ RenderResult *RE_engine_begin_result(
disprect.ymin = y;
disprect.ymax = y + h;
- result = render_result_new(re, &disprect, RR_USE_MEM, layername, viewname);
+ result = render_result_new(re, &disprect, layername, viewname);
/* TODO: make this thread safe. */
@@ -341,25 +363,12 @@ RenderResult *RE_engine_begin_result(
render_result_clone_passes(re, result, viewname);
render_result_passes_allocated_ensure(result);
- RenderPart *pa;
-
- /* Copy EXR tile settings, so pipeline knows whether this is a result
- * for Save Buffers enabled rendering.
- */
- result->do_exr_tile = re->result->do_exr_tile;
-
BLI_addtail(&engine->fullresult, result);
result->tilerect.xmin += re->disprect.xmin;
result->tilerect.xmax += re->disprect.xmin;
result->tilerect.ymin += re->disprect.ymin;
result->tilerect.ymax += re->disprect.ymin;
-
- pa = get_part_from_result(re, result);
-
- if (pa) {
- pa->status = PART_STATUS_IN_PROGRESS;
- }
}
return result;
@@ -426,53 +435,14 @@ void RE_engine_end_result(
re_ensure_passes_allocated_thread_safe(re);
- /* merge. on break, don't merge in result for preview renders, looks nicer */
- if (!highlight) {
- /* for exr tile render, detect tiles that are done */
- RenderPart *pa = get_part_from_result(re, result);
-
- if (pa) {
- pa->status = (!cancel && merge_results) ? PART_STATUS_MERGED : PART_STATUS_RENDERED;
- }
- else if (re->result->do_exr_tile) {
- /* If written result does not match any tile and we are using save
- * buffers, we are going to get OpenEXR save errors. */
- fprintf(stderr, "RenderEngine.end_result: dimensions do not match any OpenEXR tile.\n");
- }
- }
-
if (re->engine && (re->engine->flag & RE_ENGINE_HIGHLIGHT_TILES)) {
- BLI_mutex_lock(&re->highlighted_tiles_mutex);
-
- if (re->highlighted_tiles == NULL) {
- re->highlighted_tiles = BLI_gset_new(
- BLI_ghashutil_inthash_v4_p, BLI_ghashutil_inthash_v4_cmp, "highlighted tiles");
- }
+ const HighlightedTile tile = highlighted_tile_from_result_get(re, result);
- HighlightedTile tile = highlighted_tile_from_result_get(re, result);
- if (highlight) {
- void **tile_in_set;
- if (!BLI_gset_ensure_p_ex(re->highlighted_tiles, &tile, &tile_in_set)) {
- *tile_in_set = MEM_mallocN(sizeof(HighlightedTile), __func__);
- memcpy(*tile_in_set, &tile, sizeof(tile));
- }
- BLI_gset_add(re->highlighted_tiles, &tile);
- }
- else {
- BLI_gset_remove(re->highlighted_tiles, &tile, MEM_freeN);
- }
-
- BLI_mutex_unlock(&re->highlighted_tiles_mutex);
+ engine_tile_highlight_set(engine, &tile, highlight);
}
if (!cancel || merge_results) {
- if (re->result->do_exr_tile) {
- if (!cancel && merge_results) {
- render_result_exr_file_merge(re->result, result, re->viewname);
- render_result_merge(re->result, result);
- }
- }
- else if (!(re->test_break(re->tbh) && (re->r.scemode & R_BUTS_PREVIEW))) {
+ if (!(re->test_break(re->tbh) && (re->r.scemode & R_BUTS_PREVIEW))) {
render_result_merge(re->result, result);
}
@@ -582,6 +552,27 @@ void RE_engine_set_error_message(RenderEngine *engine, const char *msg)
}
}
+RenderPass *RE_engine_pass_by_index_get(RenderEngine *engine, const char *layer_name, int index)
+{
+ Render *re = engine->re;
+ if (re == NULL) {
+ return NULL;
+ }
+
+ RenderPass *pass = NULL;
+
+ RenderResult *rr = RE_AcquireResultRead(re);
+ if (rr != NULL) {
+ const RenderLayer *layer = RE_GetRenderLayer(rr, layer_name);
+ if (layer != NULL) {
+ pass = BLI_findlink(&layer->passes, index);
+ }
+ }
+ RE_ReleaseResult(re);
+
+ return pass;
+}
+
const char *RE_engine_active_view_get(RenderEngine *engine)
{
Render *re = engine->re;
@@ -837,12 +828,6 @@ bool RE_bake_engine(Render *re,
engine->resolution_x = re->winx;
engine->resolution_y = re->winy;
- BLI_rw_mutex_lock(&re->partsmutex, THREAD_LOCK_WRITE);
- RE_parts_init(re);
- engine->tile_x = re->r.tilex;
- engine->tile_y = re->r.tiley;
- BLI_rw_mutex_unlock(&re->partsmutex);
-
if (type->bake) {
engine->depsgraph = depsgraph;
@@ -870,21 +855,13 @@ bool RE_bake_engine(Render *re,
engine->depsgraph = NULL;
}
- engine->tile_x = 0;
- engine->tile_y = 0;
engine->flag &= ~RE_ENGINE_RENDERING;
- /* Free depsgraph outside of parts mutex lock, since this locks OpenGL context
- * while the UI drawing might also lock the OpenGL context and parts mutex. */
engine_depsgraph_free(engine);
- BLI_rw_mutex_lock(&re->partsmutex, THREAD_LOCK_WRITE);
RE_engine_free(engine);
re->engine = NULL;
- RE_parts_free(re);
- BLI_rw_mutex_unlock(&re->partsmutex);
-
if (BKE_reports_contain(re->reports, RPT_ERROR)) {
G.is_break = true;
}
@@ -928,15 +905,23 @@ static void engine_render_view_layer(Render *re,
DRW_render_context_enable(engine->re);
}
+ BLI_mutex_lock(&engine->re->engine_draw_mutex);
+ re->engine->flag |= RE_ENGINE_CAN_DRAW;
+ BLI_mutex_unlock(&engine->re->engine_draw_mutex);
+
engine->type->render(engine, engine->depsgraph);
+ BLI_mutex_lock(&engine->re->engine_draw_mutex);
+ re->engine->flag &= ~RE_ENGINE_CAN_DRAW;
+ BLI_mutex_unlock(&engine->re->engine_draw_mutex);
+
if (use_gpu_context) {
DRW_render_context_disable(engine->re);
}
}
/* Optionally composite grease pencil over render result. */
- if (engine->has_grease_pencil && use_grease_pencil && !re->result->do_exr_tile) {
+ if (engine->has_grease_pencil && use_grease_pencil) {
/* NOTE: External engine might have been requested to free its
* dependency graph, which is only allowed if there is no grease
* pencil (pipeline is taking care of that). */
@@ -981,16 +966,11 @@ bool RE_engine_render(Render *re, bool do_all)
/* create render result */
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
if (re->result == NULL || !(re->r.scemode & R_BUTS_PREVIEW)) {
- int savebuffers = RR_USE_MEM;
-
if (re->result) {
render_result_free(re->result);
}
- if ((type->flag & RE_USE_SAVE_BUFFERS) && (re->r.scemode & R_EXR_TILE_FILE)) {
- savebuffers = RR_USE_EXR;
- }
- re->result = render_result_new(re, &re->disprect, savebuffers, RR_ALL_LAYERS, RR_ALL_VIEWS);
+ re->result = render_result_new(re, &re->disprect, RR_ALL_LAYERS, RR_ALL_VIEWS);
}
BLI_rw_mutex_unlock(&re->resultmutex);
@@ -1035,32 +1015,15 @@ bool RE_engine_render(Render *re, bool do_all)
engine->resolution_x = re->winx;
engine->resolution_y = re->winy;
- BLI_rw_mutex_lock(&re->partsmutex, THREAD_LOCK_WRITE);
- RE_parts_init(re);
- engine->tile_x = re->partx;
- engine->tile_y = re->party;
- BLI_rw_mutex_unlock(&re->partsmutex);
-
- if (re->result->do_exr_tile) {
- render_result_exr_file_begin(re, engine);
- }
-
/* Clear UI drawing locks. */
if (re->draw_lock) {
re->draw_lock(re->dlh, false);
}
- /* Render view layers. */
- bool delay_grease_pencil = false;
-
if (type->render) {
FOREACH_VIEW_LAYER_TO_RENDER_BEGIN (re, view_layer_iter) {
engine_render_view_layer(re, engine, view_layer_iter, true, true);
- /* With save buffers there is no render buffer in memory for compositing, delay
- * grease pencil in that case. */
- delay_grease_pencil = engine->has_grease_pencil && re->result->do_exr_tile;
-
if (RE_engine_test_break(engine)) {
break;
}
@@ -1068,42 +1031,18 @@ bool RE_engine_render(Render *re, bool do_all)
FOREACH_VIEW_LAYER_TO_RENDER_END;
}
+ if (type->render_frame_finish) {
+ type->render_frame_finish(engine);
+ }
+
/* Clear tile data */
- engine->tile_x = 0;
- engine->tile_y = 0;
engine->flag &= ~RE_ENGINE_RENDERING;
render_result_free_list(&engine->fullresult, engine->fullresult.first);
- BLI_rw_mutex_lock(&re->partsmutex, THREAD_LOCK_WRITE);
-
- /* For save buffers, read back from disk. */
- if (re->result->do_exr_tile) {
- render_result_exr_file_end(re, engine);
- }
-
- /* Perform delayed grease pencil rendering. */
- if (delay_grease_pencil) {
- BLI_rw_mutex_unlock(&re->partsmutex);
-
- FOREACH_VIEW_LAYER_TO_RENDER_BEGIN (re, view_layer_iter) {
- engine_render_view_layer(re, engine, view_layer_iter, false, true);
- if (RE_engine_test_break(engine)) {
- break;
- }
- }
- FOREACH_VIEW_LAYER_TO_RENDER_END;
-
- BLI_rw_mutex_lock(&re->partsmutex, THREAD_LOCK_WRITE);
- }
-
/* re->engine becomes zero if user changed active render engine during render */
if (!engine_keep_depsgraph(engine) || !re->engine) {
- /* Free depsgraph outside of parts mutex lock, since this locks OpenGL context
- * while the UI drawing might also lock the OpenGL context and parts mutex. */
- BLI_rw_mutex_unlock(&re->partsmutex);
engine_depsgraph_free(engine);
- BLI_rw_mutex_lock(&re->partsmutex, THREAD_LOCK_WRITE);
RE_engine_free(engine);
re->engine = NULL;
@@ -1115,9 +1054,6 @@ bool RE_engine_render(Render *re, bool do_all)
BLI_rw_mutex_unlock(&re->resultmutex);
}
- RE_parts_free(re);
- BLI_rw_mutex_unlock(&re->partsmutex);
-
if (BKE_reports_contain(re->reports, RPT_ERROR)) {
G.is_break = true;
}
@@ -1179,3 +1115,81 @@ void RE_engine_free_blender_memory(RenderEngine *engine)
}
engine_depsgraph_free(engine);
}
+
+struct RenderEngine *RE_engine_get(const Render *re)
+{
+ return re->engine;
+}
+
+bool RE_engine_draw_acquire(Render *re)
+{
+ BLI_mutex_lock(&re->engine_draw_mutex);
+
+ RenderEngine *engine = re->engine;
+
+ if (engine == NULL || engine->type->draw == NULL || (engine->flag & RE_ENGINE_CAN_DRAW) == 0) {
+ BLI_mutex_unlock(&re->engine_draw_mutex);
+ return false;
+ }
+
+ return true;
+}
+
+void RE_engine_draw_release(Render *re)
+{
+ BLI_mutex_unlock(&re->engine_draw_mutex);
+}
+
+void RE_engine_tile_highlight_set(
+ RenderEngine *engine, int x, int y, int width, int height, bool highlight)
+{
+ HighlightedTile tile;
+ BLI_rcti_init(&tile.rect, x, x + width, y, y + height);
+
+ engine_tile_highlight_set(engine, &tile, highlight);
+}
+
+void RE_engine_tile_highlight_clear_all(RenderEngine *engine)
+{
+ if ((engine->flag & RE_ENGINE_HIGHLIGHT_TILES) == 0) {
+ return;
+ }
+
+ Render *re = engine->re;
+
+ BLI_mutex_lock(&re->highlighted_tiles_mutex);
+
+ if (re->highlighted_tiles != NULL) {
+ BLI_gset_clear(re->highlighted_tiles, MEM_freeN);
+ }
+
+ BLI_mutex_unlock(&re->highlighted_tiles_mutex);
+}
+
+/* -------------------------------------------------------------------- */
+/** \name OpenGL context manipulation.
+ *
+ * NOTE: Only used for Cycles's BLenderGPUDisplay integration with the draw manager. A subject
+ * for re-consideration. Do not use this functionality.
+ * \{ */
+
+bool RE_engine_has_render_context(RenderEngine *engine)
+{
+ if (engine->re == NULL) {
+ return false;
+ }
+
+ return RE_gl_context_get(engine->re) != NULL;
+}
+
+void RE_engine_render_context_enable(RenderEngine *engine)
+{
+ DRW_render_context_enable(engine->re);
+}
+
+void RE_engine_render_context_disable(RenderEngine *engine)
+{
+ DRW_render_context_disable(engine->re);
+}
+
+/** \} */
diff --git a/source/blender/render/intern/initrender.c b/source/blender/render/intern/initrender.c
index 3148625c866..2370d8e893b 100644
--- a/source/blender/render/intern/initrender.c
+++ b/source/blender/render/intern/initrender.c
@@ -43,9 +43,6 @@
#include "pipeline.h"
#include "render_types.h"
-/* Own includes */
-#include "initrender.h"
-
/* ****************** MASKS and LUTS **************** */
static float filt_quadratic(float x)
@@ -244,91 +241,3 @@ void RE_GetViewPlane(Render *re, rctf *r_viewplane, rcti *r_disprect)
BLI_rcti_init(r_disprect, 0, 0, 0, 0);
}
}
-
-/* ~~~~~~~~~~~~~~~~ part (tile) calculus ~~~~~~~~~~~~~~~~~~~~~~ */
-
-void RE_parts_free(Render *re)
-{
- if (re->parts) {
- BLI_ghash_free(re->parts, NULL, MEM_freeN);
- re->parts = NULL;
- }
-}
-
-void RE_parts_clamp(Render *re)
-{
- /* part size */
- re->partx = max_ii(1, min_ii(re->r.tilex, re->rectx));
- re->party = max_ii(1, min_ii(re->r.tiley, re->recty));
-}
-
-void RE_parts_init(Render *re)
-{
- int nr, xd, yd, partx, party, xparts, yparts;
- int xminb, xmaxb, yminb, ymaxb;
-
- RE_parts_free(re);
-
- re->parts = BLI_ghash_new(
- BLI_ghashutil_inthash_v4_p, BLI_ghashutil_inthash_v4_cmp, "render parts");
-
- /* Just for readable code. */
- xminb = re->disprect.xmin;
- yminb = re->disprect.ymin;
- xmaxb = re->disprect.xmax;
- ymaxb = re->disprect.ymax;
-
- RE_parts_clamp(re);
-
- partx = re->partx;
- party = re->party;
- /* part count */
- xparts = (re->rectx + partx - 1) / partx;
- yparts = (re->recty + party - 1) / party;
-
- for (nr = 0; nr < xparts * yparts; nr++) {
- rcti disprect;
- int rectx, recty;
-
- xd = (nr % xparts);
- yd = (nr - xd) / xparts;
-
- disprect.xmin = xminb + xd * partx;
- disprect.ymin = yminb + yd * party;
-
- /* ensure we cover the entire picture, so last parts go to end */
- if (xd < xparts - 1) {
- disprect.xmax = disprect.xmin + partx;
- if (disprect.xmax > xmaxb) {
- disprect.xmax = xmaxb;
- }
- }
- else {
- disprect.xmax = xmaxb;
- }
-
- if (yd < yparts - 1) {
- disprect.ymax = disprect.ymin + party;
- if (disprect.ymax > ymaxb) {
- disprect.ymax = ymaxb;
- }
- }
- else {
- disprect.ymax = ymaxb;
- }
-
- rectx = BLI_rcti_size_x(&disprect);
- recty = BLI_rcti_size_y(&disprect);
-
- /* so, now can we add this part? */
- if (rectx > 0 && recty > 0) {
- RenderPart *pa = MEM_callocN(sizeof(RenderPart), "new part");
-
- pa->disprect = disprect;
- pa->rectx = rectx;
- pa->recty = recty;
-
- BLI_ghash_insert(re->parts, &pa->disprect, pa);
- }
- }
-}
diff --git a/source/blender/render/intern/initrender.h b/source/blender/render/intern/initrender.h
deleted file mode 100644
index f5ac352752f..00000000000
--- a/source/blender/render/intern/initrender.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup render
- */
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Functions */
-
-void RE_parts_init(Render *re);
-void RE_parts_free(Render *re);
-void RE_parts_clamp(Render *re);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/source/blender/render/intern/pipeline.c b/source/blender/render/intern/pipeline.c
index 5418f4035b1..72ff920561d 100644
--- a/source/blender/render/intern/pipeline.c
+++ b/source/blender/render/intern/pipeline.c
@@ -102,7 +102,6 @@
#include "DEG_depsgraph.h"
/* internal */
-#include "initrender.h"
#include "pipeline.h"
#include "render_result.h"
#include "render_types.h"
@@ -568,7 +567,7 @@ Render *RE_NewRender(const char *name)
BLI_addtail(&RenderGlobal.renderlist, re);
BLI_strncpy(re->name, name, RE_MAXNAME);
BLI_rw_mutex_init(&re->resultmutex);
- BLI_rw_mutex_init(&re->partsmutex);
+ BLI_mutex_init(&re->engine_draw_mutex);
BLI_mutex_init(&re->highlighted_tiles_mutex);
}
@@ -633,7 +632,7 @@ void RE_FreeRender(Render *re)
}
BLI_rw_mutex_end(&re->resultmutex);
- BLI_rw_mutex_end(&re->partsmutex);
+ BLI_mutex_end(&re->engine_draw_mutex);
BLI_mutex_end(&re->highlighted_tiles_mutex);
BLI_freelistN(&re->view_layers);
@@ -722,26 +721,6 @@ void RE_FreePersistentData(const Scene *scene)
/* ********* initialize state ******** */
-/* clear full sample and tile flags if needed */
-static int check_mode_full_sample(RenderData *rd)
-{
- int scemode = rd->scemode;
-
- /* not supported by any current renderer */
- scemode &= ~R_FULL_SAMPLE;
-
-#ifdef WITH_OPENEXR
- if (scemode & R_FULL_SAMPLE) {
- scemode |= R_EXR_TILE_FILE; /* enable automatic */
- }
-#else
- /* can't do this without openexr support */
- scemode &= ~(R_EXR_TILE_FILE | R_FULL_SAMPLE);
-#endif
-
- return scemode;
-}
-
static void re_init_resolution(Render *re, Render *source, int winx, int winy, rcti *disprect)
{
re->winx = winx;
@@ -839,8 +818,6 @@ void RE_InitState(Render *re,
return;
}
- re->r.scemode = check_mode_full_sample(&re->r);
-
if (single_layer) {
int index = BLI_findindex(render_layers, single_layer);
if (index != -1) {
@@ -890,9 +867,6 @@ void RE_InitState(Render *re,
render_result_view_new(re->result, "");
}
- /* ensure renderdatabase can use part settings correct */
- RE_parts_clamp(re);
-
BLI_rw_mutex_unlock(&re->resultmutex);
RE_init_threadcount(re);
@@ -1040,7 +1014,7 @@ static void render_result_uncrop(Render *re)
/* weak is: it chances disprect from border */
render_result_disprect_to_full_resolution(re);
- rres = render_result_new(re, &re->disprect, RR_USE_MEM, RR_ALL_LAYERS, RR_ALL_VIEWS);
+ rres = render_result_new(re, &re->disprect, RR_ALL_LAYERS, RR_ALL_VIEWS);
render_result_passes_allocated_ensure(rres);
rres->stamp_data = BKE_stamp_data_copy(re->result->stamp_data);
@@ -1227,7 +1201,7 @@ static void do_render_compositor(Render *re)
if ((re->r.mode & R_CROP) == 0) {
render_result_disprect_to_full_resolution(re);
}
- re->result = render_result_new(re, &re->disprect, RR_USE_MEM, RR_ALL_LAYERS, RR_ALL_VIEWS);
+ re->result = render_result_new(re, &re->disprect, RR_ALL_LAYERS, RR_ALL_VIEWS);
BLI_rw_mutex_unlock(&re->resultmutex);
@@ -1647,7 +1621,7 @@ bool RE_is_rendering_allowed(Scene *scene,
Object *camera_override,
ReportList *reports)
{
- int scemode = check_mode_full_sample(&scene->r);
+ const int scemode = scene->r.scemode;
if (scene->r.mode & R_BORDER) {
if (scene->r.border.xmax <= scene->r.border.xmin ||
@@ -1657,17 +1631,6 @@ bool RE_is_rendering_allowed(Scene *scene,
}
}
- if (scemode & (R_EXR_TILE_FILE | R_FULL_SAMPLE)) {
- char str[FILE_MAX];
-
- render_result_exr_file_path(scene, "", 0, str);
-
- if (!BLI_file_is_writable(str)) {
- BKE_report(reports, RPT_ERROR, "Cannot save render buffers, check the temp default path");
- return 0;
- }
- }
-
if (RE_seq_render_active(scene, &scene->r)) {
/* Sequencer */
if (scene->r.mode & R_BORDER) {
@@ -1686,13 +1649,6 @@ bool RE_is_rendering_allowed(Scene *scene,
BKE_report(reports, RPT_ERROR, "No render output node in scene");
return 0;
}
-
- if (scemode & R_FULL_SAMPLE) {
- if (compositor_needs_render(scene, 0) == 0) {
- BKE_report(reports, RPT_ERROR, "Full sample AA not supported without 3D rendering");
- return 0;
- }
- }
}
else {
/* Regular Render */
@@ -1710,14 +1666,6 @@ bool RE_is_rendering_allowed(Scene *scene,
return 1;
}
-static void validate_render_settings(Render *re)
-{
- if (RE_engine_is_external(re)) {
- /* not supported yet */
- re->r.scemode &= ~R_FULL_SAMPLE;
- }
-}
-
static void update_physics_cache(Render *re,
Scene *scene,
ViewLayer *view_layer,
@@ -1820,8 +1768,6 @@ static int render_init_from_main(Render *re,
/* initstate makes new result, have to send changed tags around */
ntreeCompositTagRender(re->scene);
- validate_render_settings(re);
-
re->display_init(re->dih, re->result);
re->display_clear(re->dch, re->result);
diff --git a/source/blender/render/intern/render_result.c b/source/blender/render/intern/render_result.c
index 6cb6aabe885..c308147fc5b 100644
--- a/source/blender/render/intern/render_result.c
+++ b/source/blender/render/intern/render_result.c
@@ -260,8 +260,10 @@ RenderPass *render_layer_add_pass(RenderResult *rr,
/* will read info from Render *re to define layers */
/* called in threads */
/* re->winx,winy is coordinate space of entire image, partrct the part within */
-RenderResult *render_result_new(
- Render *re, rcti *partrct, int savebuffers, const char *layername, const char *viewname)
+RenderResult *render_result_new(Render *re,
+ rcti *partrct,
+ const char *layername,
+ const char *viewname)
{
RenderResult *rr;
RenderLayer *rl;
@@ -287,10 +289,6 @@ RenderResult *render_result_new(
rr->tilerect.ymin = partrct->ymin - re->disprect.ymin;
rr->tilerect.ymax = partrct->ymax - re->disprect.ymin;
- if (savebuffers) {
- rr->do_exr_tile = true;
- }
-
rr->passes_allocated = false;
render_result_views_new(rr, &re->r);
@@ -314,10 +312,6 @@ RenderResult *render_result_new(
rl->rectx = rectx;
rl->recty = recty;
- if (rr->do_exr_tile) {
- rl->exrhandle = IMB_exr_get_handle();
- }
-
for (rv = rr->views.first; rv; rv = rv->next) {
const char *view = rv->name;
@@ -327,10 +321,6 @@ RenderResult *render_result_new(
}
}
- if (rr->do_exr_tile) {
- IMB_exr_add_view(rl->exrhandle, view);
- }
-
#define RENDER_LAYER_ADD_PASS_SAFE(rr, rl, channels, name, viewname, chan_id) \
do { \
if (render_layer_add_pass(rr, rl, channels, name, viewname, chan_id) == NULL) { \
@@ -351,6 +341,9 @@ RenderResult *render_result_new(
if (view_layer->passflag & SCE_PASS_NORMAL) {
RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_NORMAL, view, "XYZ");
}
+ if (view_layer->passflag & SCE_PASS_POSITION) {
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_POSITION, view, "XYZ");
+ }
if (view_layer->passflag & SCE_PASS_UV) {
RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_UV, view, "UVA");
}
@@ -424,11 +417,6 @@ RenderResult *render_result_new(
rl->rectx = rectx;
rl->recty = recty;
- /* duplicate code... */
- if (rr->do_exr_tile) {
- rl->exrhandle = IMB_exr_get_handle();
- }
-
for (rv = rr->views.first; rv; rv = rv->next) {
const char *view = rv->name;
@@ -438,10 +426,6 @@ RenderResult *render_result_new(
}
}
- if (rr->do_exr_tile) {
- IMB_exr_add_view(rl->exrhandle, view);
- }
-
/* a renderlayer should always have a Combined pass */
render_layer_add_pass(rr, rl, 4, RE_PASSNAME_COMBINED, view, "RGBA");
}
@@ -1089,227 +1073,6 @@ void render_result_single_layer_end(Render *re)
re->pushedresult = NULL;
}
-/************************* EXR Tile File Rendering ***************************/
-
-static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart, const char *viewname)
-{
- RenderLayer *rlp, *rl;
- RenderPass *rpassp;
- int partx, party;
-
- BLI_thread_lock(LOCK_IMAGE);
-
- for (rlp = rrpart->layers.first; rlp; rlp = rlp->next) {
- rl = RE_GetRenderLayer(rr, rlp->name);
-
- /* should never happen but prevents crash if it does */
- BLI_assert(rl);
- if (UNLIKELY(rl == NULL)) {
- continue;
- }
-
- /* passes are allocated in sync */
- for (rpassp = rlp->passes.first; rpassp; rpassp = rpassp->next) {
- const int xstride = rpassp->channels;
- int a;
- char fullname[EXR_PASS_MAXNAME];
-
- for (a = 0; a < xstride; a++) {
- set_pass_full_name(fullname, rpassp->name, a, viewname, rpassp->chan_id);
-
- IMB_exr_set_channel(rl->exrhandle,
- rlp->name,
- fullname,
- xstride,
- xstride * rrpart->rectx,
- rpassp->rect + a);
- }
- }
- }
-
- party = rrpart->tilerect.ymin;
- partx = rrpart->tilerect.xmin;
-
- for (rlp = rrpart->layers.first; rlp; rlp = rlp->next) {
- rl = RE_GetRenderLayer(rr, rlp->name);
-
- /* should never happen but prevents crash if it does */
- BLI_assert(rl);
- if (UNLIKELY(rl == NULL)) {
- continue;
- }
-
- IMB_exrtile_write_channels(rl->exrhandle, partx, party, 0, viewname, false);
- }
-
- BLI_thread_unlock(LOCK_IMAGE);
-}
-
-void render_result_save_empty_result_tiles(Render *re)
-{
- RenderResult *rr;
- RenderLayer *rl;
-
- for (rr = re->result; rr; rr = rr->next) {
- for (rl = rr->layers.first; rl; rl = rl->next) {
- GHashIterator pa_iter;
- GHASH_ITER (pa_iter, re->parts) {
- RenderPart *pa = BLI_ghashIterator_getValue(&pa_iter);
- if (pa->status != PART_STATUS_MERGED) {
- int party = pa->disprect.ymin - re->disprect.ymin;
- int partx = pa->disprect.xmin - re->disprect.xmin;
- IMB_exrtile_write_channels(rl->exrhandle, partx, party, 0, re->viewname, true);
- }
- }
- }
- }
-}
-
-/* Compute list of passes needed by render engine. */
-static void templates_register_pass_cb(void *userdata,
- Scene *UNUSED(scene),
- ViewLayer *UNUSED(view_layer),
- const char *name,
- int channels,
- const char *chan_id,
- eNodeSocketDatatype UNUSED(type))
-{
- ListBase *templates = userdata;
- RenderPass *pass = MEM_callocN(sizeof(RenderPass), "RenderPassTemplate");
-
- pass->channels = channels;
- BLI_strncpy(pass->name, name, sizeof(pass->name));
- BLI_strncpy(pass->chan_id, chan_id, sizeof(pass->chan_id));
-
- BLI_addtail(templates, pass);
-}
-
-static void render_result_get_pass_templates(RenderEngine *engine,
- Render *re,
- RenderLayer *rl,
- ListBase *templates)
-{
- BLI_listbase_clear(templates);
-
- if (engine && engine->type->update_render_passes) {
- ViewLayer *view_layer = BLI_findstring(&re->view_layers, rl->name, offsetof(ViewLayer, name));
- if (view_layer) {
- RE_engine_update_render_passes(
- engine, re->scene, view_layer, templates_register_pass_cb, templates);
- }
- }
-}
-
-/* begin write of exr tile file */
-void render_result_exr_file_begin(Render *re, RenderEngine *engine)
-{
- char str[FILE_MAX];
-
- for (RenderResult *rr = re->result; rr; rr = rr->next) {
- LISTBASE_FOREACH (RenderLayer *, rl, &rr->layers) {
- /* Get passes needed by engine. Normally we would wait for the
- * engine to create them, but for EXR file we need to know in
- * advance. */
- ListBase templates;
- render_result_get_pass_templates(engine, re, rl, &templates);
-
- /* Create render passes requested by engine. Only this part is
- * mutex locked to avoid deadlock with Python GIL. */
- BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
- LISTBASE_FOREACH (RenderPass *, pass, &templates) {
- RE_create_render_pass(
- re->result, pass->name, pass->channels, pass->chan_id, rl->name, NULL);
- }
- BLI_rw_mutex_unlock(&re->resultmutex);
-
- BLI_freelistN(&templates);
-
- /* Open EXR file for writing. */
- render_result_exr_file_path(re->scene, rl->name, rr->sample_nr, str);
- printf("write exr tmp file, %dx%d, %s\n", rr->rectx, rr->recty, str);
- IMB_exrtile_begin_write(rl->exrhandle, str, 0, rr->rectx, rr->recty, re->partx, re->party);
- }
- }
-}
-
-/* end write of exr tile file, read back first sample */
-void render_result_exr_file_end(Render *re, RenderEngine *engine)
-{
- /* Preserve stamp data. */
- struct StampData *stamp_data = re->result->stamp_data;
- re->result->stamp_data = NULL;
-
- /* Close EXR files. */
- for (RenderResult *rr = re->result; rr; rr = rr->next) {
- LISTBASE_FOREACH (RenderLayer *, rl, &rr->layers) {
- IMB_exr_close(rl->exrhandle);
- rl->exrhandle = NULL;
- }
-
- rr->do_exr_tile = false;
- }
-
- /* Create new render result in memory instead of on disk. */
- BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
- render_result_free_list(&re->fullresult, re->result);
- re->result = render_result_new(re, &re->disprect, RR_USE_MEM, RR_ALL_LAYERS, RR_ALL_VIEWS);
- re->result->stamp_data = stamp_data;
- render_result_passes_allocated_ensure(re->result);
- BLI_rw_mutex_unlock(&re->resultmutex);
-
- LISTBASE_FOREACH (RenderLayer *, rl, &re->result->layers) {
- /* Get passes needed by engine. */
- ListBase templates;
- render_result_get_pass_templates(engine, re, rl, &templates);
-
- /* Create render passes requested by engine. Only this part is
- * mutex locked to avoid deadlock with Python GIL. */
- BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
- LISTBASE_FOREACH (RenderPass *, pass, &templates) {
- RE_create_render_pass(re->result, pass->name, pass->channels, pass->chan_id, rl->name, NULL);
- }
-
- BLI_freelistN(&templates);
-
- /* Render passes contents from file. */
- char str[FILE_MAXFILE + MAX_ID_NAME + MAX_ID_NAME + 100] = "";
- render_result_exr_file_path(re->scene, rl->name, 0, str);
- printf("read exr tmp file: %s\n", str);
-
- if (!render_result_exr_file_read_path(re->result, rl, str)) {
- printf("cannot read: %s\n", str);
- }
- BLI_rw_mutex_unlock(&re->resultmutex);
- }
-}
-
-/* save part into exr file */
-void render_result_exr_file_merge(RenderResult *rr, RenderResult *rrpart, const char *viewname)
-{
- for (; rr && rrpart; rr = rr->next, rrpart = rrpart->next) {
- save_render_result_tile(rr, rrpart, viewname);
- }
-}
-
-/* path to temporary exr file */
-void render_result_exr_file_path(Scene *scene, const char *layname, int sample, char *filepath)
-{
- char name[FILE_MAXFILE + MAX_ID_NAME + MAX_ID_NAME + 100];
- const char *fi = BLI_path_basename(BKE_main_blendfile_path_from_global());
-
- if (sample == 0) {
- BLI_snprintf(name, sizeof(name), "%s_%s_%s.exr", fi, scene->id.name + 2, layname);
- }
- else {
- BLI_snprintf(name, sizeof(name), "%s_%s_%s%d.exr", fi, scene->id.name + 2, layname, sample);
- }
-
- /* Make name safe for paths, see T43275. */
- BLI_filename_make_safe(name);
-
- BLI_join_dirfile(filepath, FILE_MAX, BKE_tempdir_session(), name);
-}
-
/* called for reading temp files, and for external engines */
int render_result_exr_file_read_path(RenderResult *rr,
RenderLayer *rl_single,
@@ -1416,7 +1179,7 @@ bool render_result_exr_file_cache_read(Render *re)
char *root = U.render_cachedir;
RE_FreeRenderResult(re->result);
- re->result = render_result_new(re, &re->disprect, RR_USE_MEM, RR_ALL_LAYERS, RR_ALL_VIEWS);
+ re->result = render_result_new(re, &re->disprect, RR_ALL_LAYERS, RR_ALL_VIEWS);
/* First try cache. */
render_result_exr_file_cache_path(re->scene, root, str);
diff --git a/source/blender/render/intern/render_result.h b/source/blender/render/intern/render_result.h
index 1fc64a4ea97..4145bb3b8ab 100644
--- a/source/blender/render/intern/render_result.h
+++ b/source/blender/render/intern/render_result.h
@@ -25,9 +25,6 @@
#define PASS_VECTOR_MAX 10000.0f
-#define RR_USE_MEM 0
-#define RR_USE_EXR 1
-
#define RR_ALL_LAYERS NULL
#define RR_ALL_VIEWS NULL
@@ -51,7 +48,6 @@ extern "C" {
struct RenderResult *render_result_new(struct Render *re,
struct rcti *partrct,
- int savebuffers,
const char *layername,
const char *viewname);
@@ -81,12 +77,6 @@ void render_result_free_list(struct ListBase *lb, struct RenderResult *rr);
void render_result_single_layer_begin(struct Render *re);
void render_result_single_layer_end(struct Render *re);
-/* EXR Tile File Render */
-
-void render_result_save_empty_result_tiles(struct Render *re);
-void render_result_exr_file_begin(struct Render *re, struct RenderEngine *engine);
-void render_result_exr_file_end(struct Render *re, struct RenderEngine *engine);
-
/* render pass wrapper for gpencil */
struct RenderPass *render_layer_add_pass(struct RenderResult *rr,
struct RenderLayer *rl,
@@ -95,14 +85,6 @@ struct RenderPass *render_layer_add_pass(struct RenderResult *rr,
const char *viewname,
const char *chan_id);
-void render_result_exr_file_merge(struct RenderResult *rr,
- struct RenderResult *rrpart,
- const char *viewname);
-
-void render_result_exr_file_path(struct Scene *scene,
- const char *layname,
- int sample,
- char *filepath);
int render_result_exr_file_read_path(struct RenderResult *rr,
struct RenderLayer *rl_single,
const char *filepath);
diff --git a/source/blender/render/intern/render_types.h b/source/blender/render/intern/render_types.h
index d2d2b499495..ca4f72350e1 100644
--- a/source/blender/render/intern/render_types.h
+++ b/source/blender/render/intern/render_types.h
@@ -47,30 +47,10 @@ struct ReportList;
extern "C" {
#endif
-/* this is handed over to threaded hiding/passes/shading engine */
-typedef struct RenderPart {
- struct RenderPart *next, *prev;
-
- RenderResult *result; /* result of part rendering */
- ListBase fullresult; /* optional full sample buffers */
-
- rcti disprect; /* part coordinates within total picture */
- int rectx, recty; /* the size */
- int nr; /* nr is partnr */
- short status;
-} RenderPart;
-
typedef struct HighlightedTile {
rcti rect;
} HighlightedTile;
-enum {
- /* PART_STATUS_NONE = 0, */ /* UNUSED */
- PART_STATUS_IN_PROGRESS = 1,
- PART_STATUS_RENDERED = 2,
- PART_STATUS_MERGED = 3,
-};
-
/* controls state of render, everything that's read-only during render stage */
struct Render {
struct Render *next, *prev;
@@ -91,6 +71,9 @@ struct Render {
* to not conflict with writes, so no lock used for that */
ThreadRWMutex resultmutex;
+ /* Guard for drawing render result using engine's `draw()` callback. */
+ ThreadMutex engine_draw_mutex;
+
/** Window size, display rect, viewplane.
* \note Buffer width and height with percentage applied
* without border & crop. convert to long before multiplying together to avoid overflow. */
@@ -101,10 +84,6 @@ struct Render {
/* final picture width and height (within disprect) */
int rectx, recty;
- /* real maximum size of parts after correction for minimum
- * partx*xparts can be larger than rectx, in that case last part is smaller */
- int partx, party;
-
/* Camera transform, only used by Freestyle. */
float winmat[4][4];
@@ -120,9 +99,6 @@ struct Render {
int active_view_layer;
struct Object *camera_override;
- ThreadRWMutex partsmutex;
- struct GHash *parts;
-
ThreadMutex highlighted_tiles_mutex;
struct GSet *highlighted_tiles;
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 887aed7ffc7..8baf4a0e013 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -2426,10 +2426,15 @@ void wm_window_IME_end(wmWindow *win)
void *WM_opengl_context_create(void)
{
- /* On Windows there is a problem creating contexts that share lists
- * from one context that is current in another thread.
- * So we should call this function only on the main thread.
- */
+ /* On Windows there is a problem creating contexts that share resources (almost any object,
+ * including legacy display lists, but also textures) with a context which is current in another
+ * thread. This is a documented and behavior of both `::wglCreateContextAttribsARB()` and
+ * `::wglShareLists()`.
+ *
+ * Other platforms might successfully share resources from context which is active somewhere
+ * else, but to keep our code behave the same on all platform we expect contexts to only be
+ * created from the main thread. */
+
BLI_assert(BLI_thread_is_main());
BLI_assert(GPU_framebuffer_active_get() == GPU_framebuffer_back_get());