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
diff options
context:
space:
mode:
authorJohnny Matthews <johnny.matthews@gmail.com>2022-02-02 01:48:39 +0300
committerJohnny Matthews <johnny.matthews@gmail.com>2022-02-02 01:48:39 +0300
commita1f044e9b9df70efedfc4b27cc41dc4e4cd76e9b (patch)
treecbef0cce1cd11f044b18e97bdc5cf1a65edbf152
parentb464bbb6899690e10fb83c1aba35de417d1db5e7 (diff)
parentc9b578eac8a3c0e246e9679e2333a1788d5c4031 (diff)
Merge branch 'master' into 2d
-rw-r--r--release/scripts/startup/bl_operators/wm.py66
-rw-r--r--source/blender/blenkernel/intern/hair.cc37
-rw-r--r--source/blender/blenkernel/intern/object.cc8
-rw-r--r--source/blender/draw/intern/draw_manager_shader.c7
-rw-r--r--source/blender/draw/intern/shaders/draw_hair_refine_info.hh2
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c25
-rw-r--r--source/blender/editors/space_node/node_group.cc12
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c8
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc5
-rw-r--r--source/blender/editors/transform/transform_convert.h6
-rw-r--r--source/blender/editors/transform/transform_convert_armature.c76
-rw-r--r--source/blender/editors/transform/transform_gizmo_3d.c31
-rw-r--r--source/blender/editors/util/ed_util.c6
-rw-r--r--source/blender/gpu/GPU_shader.h2
-rw-r--r--source/blender/gpu/intern/gpu_shader.cc22
-rw-r--r--source/blender/gpu/intern/gpu_shader_create_info.cc15
-rw-r--r--source/blender/gpu/intern/gpu_shader_create_info.hh24
-rw-r--r--source/blender/gpu/intern/gpu_shader_dependency.cc35
-rw-r--r--source/blender/gpu/intern/gpu_shader_dependency_private.h5
-rw-r--r--source/blender/gpu/opengl/gl_backend.cc6
-rw-r--r--source/blender/gpu/opengl/gl_context.hh2
-rw-r--r--source/blender/gpu/opengl/gl_shader.cc175
-rw-r--r--source/blender/gpu/opengl/gl_shader.hh8
-rw-r--r--source/blender/imbuf/intern/indexer.c6
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c4
-rw-r--r--source/blender/modifiers/intern/MOD_nodes.cc38
26 files changed, 451 insertions, 180 deletions
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index ce8bfa3b058..bb85ad8ca50 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -2961,93 +2961,75 @@ class WM_MT_splash_quick_setup(Menu):
bl_label = "Quick Setup"
def draw(self, context):
- wm = context.window_manager
- # prefs = context.preferences
-
layout = self.layout
-
layout.operator_context = 'EXEC_DEFAULT'
layout.label(text="Quick Setup")
- split = layout.split(factor=0.25)
+ split = layout.split(factor=0.14) # Left margin.
split.label()
- split = split.split(factor=2.0 / 3.0)
+ split = split.split(factor=0.73) # Content width.
col = split.column()
+ col.use_property_split = True
+ col.use_property_decorate = False
+
+ # Languages.
if bpy.app.build_options.international:
- sub = col.split(factor=0.35)
- row = sub.row()
- row.alignment = 'RIGHT'
- row.label(text="Language")
prefs = context.preferences
- sub.prop(prefs.view, "language", text="")
+ col.prop(prefs.view, "language")
+ col.separator()
- col.separator()
+ # Shortcuts.
+ wm = context.window_manager
+ kc = wm.keyconfigs.active
+ kc_prefs = kc.preferences
- sub = col.split(factor=0.35)
- row = sub.row()
- row.alignment = 'RIGHT'
- row.label(text="Shortcuts")
- text = bpy.path.display_name(wm.keyconfigs.active.name)
+ sub = col.column(heading="Shortcuts")
+ text = bpy.path.display_name(kc.name)
if not text:
text = "Blender"
sub.menu("USERPREF_MT_keyconfigs", text=text)
- kc = wm.keyconfigs.active
- kc_prefs = kc.preferences
has_select_mouse = hasattr(kc_prefs, "select_mouse")
if has_select_mouse:
- sub = col.split(factor=0.35)
- row = sub.row()
- row.alignment = 'RIGHT'
- row.label(text="Select With")
- sub.row().prop(kc_prefs, "select_mouse", expand=True)
- has_select_mouse = True
+ col.row().prop(kc_prefs, "select_mouse", text="Select With", expand=True)
has_spacebar_action = hasattr(kc_prefs, "spacebar_action")
if has_spacebar_action:
- sub = col.split(factor=0.35)
- row = sub.row()
- row.alignment = 'RIGHT'
- row.label(text="Spacebar")
- sub.row().prop(kc_prefs, "spacebar_action", expand=True)
- has_select_mouse = True
+ col.row().prop(kc_prefs, "spacebar_action", text="Spacebar")
col.separator()
- sub = col.split(factor=0.35)
- row = sub.row()
- row.alignment = 'RIGHT'
- row.label(text="Theme")
+ # Themes.
+ sub = col.column(heading="Theme")
label = bpy.types.USERPREF_MT_interface_theme_presets.bl_label
if label == "Presets":
label = "Blender Dark"
sub.menu("USERPREF_MT_interface_theme_presets", text=label)
- # Keep height constant
+ # Keep height constant.
if not has_select_mouse:
col.label()
if not has_spacebar_action:
col.label()
- layout.label()
+ layout.separator(factor=2.0)
- row = layout.row()
+ # Save settings buttons.
+ sub = layout.row()
- sub = row.row()
old_version = bpy.types.PREFERENCES_OT_copy_prev.previous_version()
if bpy.types.PREFERENCES_OT_copy_prev.poll(context) and old_version:
- sub.operator("preferences.copy_prev", text=iface_("Load %d.%d Settings", "Operator") % old_version)
+ sub.operator("preferences.copy_prev", text="Load %d.%d Settings" % old_version)
sub.operator("wm.save_userpref", text="Save New Settings")
else:
sub.label()
sub.label()
sub.operator("wm.save_userpref", text="Next")
- layout.separator()
- layout.separator()
+ layout.separator(factor=2.4)
class WM_MT_splash(Menu):
diff --git a/source/blender/blenkernel/intern/hair.cc b/source/blender/blenkernel/intern/hair.cc
index 976e75822bc..5e8b81c03a4 100644
--- a/source/blender/blenkernel/intern/hair.cc
+++ b/source/blender/blenkernel/intern/hair.cc
@@ -31,7 +31,7 @@
#include "BLI_listbase.h"
#include "BLI_math_base.h"
#include "BLI_math_vec_types.hh"
-#include "BLI_rand.h"
+#include "BLI_rand.hh"
#include "BLI_string.h"
#include "BLI_utildefines.h"
@@ -54,6 +54,7 @@
#include "BLO_read_write.h"
using blender::float3;
+using blender::RandomNumberGenerator;
static const char *HAIR_ATTR_POSITION = "position";
static const char *HAIR_ATTR_RADIUS = "radius";
@@ -220,38 +221,32 @@ static void hair_random(Hair *hair)
CustomData_realloc(&hair->cdata, hair->totcurve);
BKE_hair_update_customdata_pointers(hair);
- RNG *rng = BLI_rng_new(0);
+ RandomNumberGenerator rng;
for (int i = 0; i < hair->totcurve; i++) {
HairCurve *curve = &hair->curves[i];
curve->firstpoint = i * numpoints;
curve->numpoints = numpoints;
- float theta = 2.0f * M_PI * BLI_rng_get_float(rng);
- float phi = saacosf(2.0f * BLI_rng_get_float(rng) - 1.0f);
+ const float theta = 2.0f * M_PI * rng.get_float();
+ const float phi = saacosf(2.0f * rng.get_float() - 1.0f);
- float no[3] = {sinf(theta) * sinf(phi), cosf(theta) * sinf(phi), cosf(phi)};
- normalize_v3(no);
+ float3 no = {std::sin(theta) * std::sin(phi), std::cos(theta) * std::sin(phi), std::cos(phi)};
+ blender::math::normalize(no);
- float co[3];
- copy_v3_v3(co, no);
-
- float(*curve_co)[3] = hair->co + curve->firstpoint;
- float *curve_radius = hair->radius + curve->firstpoint;
+ float(*curve_positions)[3] = hair->co + curve->firstpoint;
+ float *curve_radii = hair->radius + curve->firstpoint;
+ float3 co = no;
for (int key = 0; key < numpoints; key++) {
float t = key / (float)(numpoints - 1);
- copy_v3_v3(curve_co[key], co);
- curve_radius[key] = 0.02f * (1.0f - t);
-
- float offset[3] = {2.0f * BLI_rng_get_float(rng) - 1.0f,
- 2.0f * BLI_rng_get_float(rng) - 1.0f,
- 2.0f * BLI_rng_get_float(rng) - 1.0f};
- add_v3_v3(offset, no);
- madd_v3_v3fl(co, offset, 1.0f / numpoints);
+ copy_v3_v3(curve_positions[key], co);
+ curve_radii[key] = 0.02f * (1.0f - t);
+
+ float3 offset = float3(rng.get_float(), rng.get_float(), rng.get_float()) * 2.0f - 1.0f;
+
+ co += (offset + no) / numpoints;
}
}
-
- BLI_rng_free(rng);
}
void *BKE_hair_add(Main *bmain, const char *name)
diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc
index 403b9d353ec..41221c0e444 100644
--- a/source/blender/blenkernel/intern/object.cc
+++ b/source/blender/blenkernel/intern/object.cc
@@ -4186,7 +4186,11 @@ bool BKE_object_minmax_dupli(Depsgraph *depsgraph,
/* pass */
}
else {
- BoundBox *bb = BKE_object_boundbox_get(dob->ob);
+ Object temp_ob = *dob->ob;
+ /* Do not modify the original boundbox. */
+ temp_ob.runtime.bb = nullptr;
+ BKE_object_replace_data_on_shallow_copy(&temp_ob, dob->ob_data);
+ BoundBox *bb = BKE_object_boundbox_get(&temp_ob);
if (bb) {
int i;
@@ -4198,6 +4202,8 @@ bool BKE_object_minmax_dupli(Depsgraph *depsgraph,
ok = true;
}
+
+ MEM_SAFE_FREE(temp_ob.runtime.bb);
}
}
free_object_duplilist(lb); /* does restore */
diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c
index 4715bd62779..3cfbb3fe416 100644
--- a/source/blender/draw/intern/draw_manager_shader.c
+++ b/source/blender/draw/intern/draw_manager_shader.c
@@ -50,8 +50,6 @@
static CLG_LogRef LOG = {"draw.manager.shader"};
-extern char datatoc_gpu_shader_2D_vert_glsl[];
-extern char datatoc_gpu_shader_3D_vert_glsl[];
extern char datatoc_gpu_shader_depth_only_frag_glsl[];
extern char datatoc_common_fullscreen_vert_glsl[];
@@ -620,8 +618,9 @@ static uint32_t drw_shader_dependencies_get(const DRWShaderLibrary *lib, const c
}
dbg_name[i + 1] = '\0';
- CLOG_WARN(&LOG,
- "Error: Dependency not found: %s\n"
+ CLOG_INFO(&LOG,
+ 0,
+ "Dependency '%s' not found\n"
"This might be due to bad lib ordering or overriding a builtin shader.\n",
dbg_name);
}
diff --git a/source/blender/draw/intern/shaders/draw_hair_refine_info.hh b/source/blender/draw/intern/shaders/draw_hair_refine_info.hh
index b41be7d8605..bdfc26b7dcd 100644
--- a/source/blender/draw/intern/shaders/draw_hair_refine_info.hh
+++ b/source/blender/draw/intern/shaders/draw_hair_refine_info.hh
@@ -25,7 +25,7 @@
GPU_SHADER_CREATE_INFO(draw_hair_refine_compute)
.local_group_size(1, 1)
- .storage_buf(0, Qualifier::WRITE_ONLY, "vec4", "posTime[]")
+ .storage_buf(0, Qualifier::WRITE, "vec4", "posTime[]")
.sampler(0, ImageType::FLOAT_BUFFER, "hairPointBuffer")
.sampler(1, ImageType::UINT_BUFFER, "hairStrandBuffer")
.sampler(2, ImageType::UINT_BUFFER, "hairStrandSegBuffer")
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index e71a56894d0..afb786da8c6 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -4626,6 +4626,31 @@ static int gpencil_stroke_separate_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "Not implemented!");
}
else {
+ /* Check if all points are selected. */
+ bool all_points_selected = true;
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if ((pt->flag & GP_SPOINT_SELECT) == 0) {
+ all_points_selected = false;
+ break;
+ }
+ }
+
+ /* Separate the entrie stroke. */
+ if (all_points_selected) {
+ /* deselect old stroke */
+ gps->flag &= ~GP_STROKE_SELECT;
+ BKE_gpencil_stroke_select_index_reset(gps);
+ /* unlink from source frame */
+ BLI_remlink(&gpf->strokes, gps);
+ gps->prev = gps->next = NULL;
+ /* relink to destination frame */
+ BLI_addtail(&gpf_dst->strokes, gps);
+ /* Reassign material. */
+ gps->mat_nr = idx;
+
+ continue;
+ }
+
/* make copy of source stroke */
bGPDstroke *gps_dst = BKE_gpencil_stroke_duplicate(gps, true, true);
diff --git a/source/blender/editors/space_node/node_group.cc b/source/blender/editors/space_node/node_group.cc
index 73e419d667a..3d3f8378916 100644
--- a/source/blender/editors/space_node/node_group.cc
+++ b/source/blender/editors/space_node/node_group.cc
@@ -776,6 +776,18 @@ static void node_group_make_insert_selected(const bContext &C, bNodeTree &ntree,
ListBase anim_basepaths = {nullptr, nullptr};
+ /* Detach unselected nodes inside frames when the frame is put into the group. Otherwise the
+ * `parent` pointer becomes dangling. */
+ LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
+ if (node->parent == nullptr) {
+ continue;
+ }
+ if (node_group_make_use_node(*node->parent, gnode) &&
+ !node_group_make_use_node(*node, gnode)) {
+ nodeDetachNode(node);
+ }
+ }
+
/* move nodes over */
LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree.nodes) {
if (node_group_make_use_node(*node, gnode)) {
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index 15ee35f375d..aef6b30986d 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -739,15 +739,15 @@ static int sequencer_add_movie_strip_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- /* Free custom data. */
- sequencer_add_cancel(C, op);
- SEQ_collection_free(movie_strips);
-
seq_build_proxy(C, movie_strips);
DEG_relations_tag_update(bmain);
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
+ /* Free custom data. */
+ sequencer_add_cancel(C, op);
+ SEQ_collection_free(movie_strips);
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
index b9b03732a40..83302f94c85 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
@@ -474,6 +474,11 @@ static void find_fields_to_evaluate(const SpaceSpreadsheet *sspreadsheet,
r_fields.add("Viewer", std::move(field));
}
}
+ if (const geo_log::GenericValueLog *generic_value_log =
+ dynamic_cast<const geo_log::GenericValueLog *>(value_log)) {
+ fn::GPointer value = generic_value_log->value();
+ r_fields.add("Viewer", fn::make_constant_field(*value.type(), value.get()));
+ }
}
}
diff --git a/source/blender/editors/transform/transform_convert.h b/source/blender/editors/transform/transform_convert.h
index c40f3c28a79..90f78d4abf1 100644
--- a/source/blender/editors/transform/transform_convert.h
+++ b/source/blender/editors/transform/transform_convert.h
@@ -124,10 +124,8 @@ void special_aftertrans_update__actedit(bContext *C, TransInfo *t);
* Sets transform flags in the bones.
* Returns total number of bones with #BONE_TRANSFORM.
*/
-int transform_convert_pose_transflags_update(Object *ob,
- int mode,
- short around,
- bool has_translate_rotate[2]);
+void transform_convert_pose_transflags_update(Object *ob, int mode, short around);
+
/**
* When objects array is NULL, use 't->data_container' as is.
*/
diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c
index 5d0a3bd9dd1..2a696dd0593 100644
--- a/source/blender/editors/transform/transform_convert_armature.c
+++ b/source/blender/editors/transform/transform_convert_armature.c
@@ -739,9 +739,41 @@ void createTransPose(TransInfo *t)
const bool mirror = ((pose->flag & POSE_MIRROR_EDIT) != 0);
- /* set flags and count total */
- tc->data_len = transform_convert_pose_transflags_update(
- ob, t->mode, t->around, has_translate_rotate);
+ /* Set flags. */
+ transform_convert_pose_transflags_update(ob, t->mode, t->around);
+
+ /* Now count, and check if we have autoIK or have to switch from translate to rotate. */
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
+ Bone *bone = pchan->bone;
+ if (!(bone->flag & BONE_TRANSFORM)) {
+ continue;
+ }
+
+ tc->data_len++;
+
+ if (has_translate_rotate[0] && has_translate_rotate[1]) {
+ continue;
+ }
+
+ if (has_targetless_ik(pchan) == NULL) {
+ if (pchan->parent && (bone->flag & BONE_CONNECTED)) {
+ if (bone->flag & BONE_HINGE_CHILD_TRANSFORM) {
+ has_translate_rotate[0] = true;
+ }
+ }
+ else {
+ if ((pchan->protectflag & OB_LOCK_LOC) != OB_LOCK_LOC) {
+ has_translate_rotate[0] = true;
+ }
+ }
+ if ((pchan->protectflag & OB_LOCK_ROT) != OB_LOCK_ROT) {
+ has_translate_rotate[1] = true;
+ }
+ }
+ else {
+ has_translate_rotate[0] = true;
+ }
+ }
if (tc->data_len == 0) {
continue;
@@ -1499,15 +1531,11 @@ static void bone_children_clear_transflag(int mode, short around, ListBase *lb)
}
}
-int transform_convert_pose_transflags_update(Object *ob,
- const int mode,
- const short around,
- bool has_translate_rotate[2])
+void transform_convert_pose_transflags_update(Object *ob, const int mode, const short around)
{
bArmature *arm = ob->data;
bPoseChannel *pchan;
Bone *bone;
- int total = 0;
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
bone = pchan->bone;
@@ -1537,36 +1565,6 @@ int transform_convert_pose_transflags_update(Object *ob,
}
}
}
- /* now count, and check if we have autoIK or have to switch from translate to rotate */
- for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
- bone = pchan->bone;
- if (bone->flag & BONE_TRANSFORM) {
- total++;
-
- if (has_translate_rotate != NULL) {
- if (has_targetless_ik(pchan) == NULL) {
- if (pchan->parent && (pchan->bone->flag & BONE_CONNECTED)) {
- if (pchan->bone->flag & BONE_HINGE_CHILD_TRANSFORM) {
- has_translate_rotate[0] = true;
- }
- }
- else {
- if ((pchan->protectflag & OB_LOCK_LOC) != OB_LOCK_LOC) {
- has_translate_rotate[0] = true;
- }
- }
- if ((pchan->protectflag & OB_LOCK_ROT) != OB_LOCK_ROT) {
- has_translate_rotate[1] = true;
- }
- }
- else {
- has_translate_rotate[0] = true;
- }
- }
- }
- }
-
- return total;
}
static short apply_targetless_ik(Object *ob)
@@ -1733,7 +1731,7 @@ void special_aftertrans_update__pose(bContext *C, TransInfo *t)
/* Set BONE_TRANSFORM flags for auto-key, gizmo draw might have changed them. */
if (!canceled && (t->mode != TFM_DUMMY)) {
- transform_convert_pose_transflags_update(ob, t->mode, t->around, NULL);
+ transform_convert_pose_transflags_update(ob, t->mode, t->around);
}
/* if target-less IK grabbing, we calculate the pchan transforms and clear flag */
diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c
index 9bd55d78039..c1f36951f64 100644
--- a/source/blender/editors/transform/transform_gizmo_3d.c
+++ b/source/blender/editors/transform/transform_gizmo_3d.c
@@ -953,32 +953,27 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob_iter = objects[ob_index];
- const bool use_mat_local = (ob_iter != ob);
+ const bool use_mat_local = params->use_local_axis && (ob_iter != ob);
bPoseChannel *pchan;
/* mislead counting bones... bah. We don't know the gizmo mode, could be mixed */
const int mode = TFM_ROTATION;
- const int totsel_iter = transform_convert_pose_transflags_update(
- ob_iter, mode, V3D_AROUND_CENTER_BOUNDS, NULL);
+ transform_convert_pose_transflags_update(ob_iter, mode, V3D_AROUND_CENTER_BOUNDS);
- if (totsel_iter) {
- float mat_local[4][4];
- if (params->use_local_axis) {
- if (use_mat_local) {
- mul_m4_m4m4(mat_local, ob->imat, ob_iter->obmat);
- }
- }
+ float mat_local[4][4];
+ if (use_mat_local) {
+ mul_m4_m4m4(mat_local, ob->imat, ob_iter->obmat);
+ }
- /* use channels to get stats */
- for (pchan = ob_iter->pose->chanbase.first; pchan; pchan = pchan->next) {
- Bone *bone = pchan->bone;
- if (bone && (bone->flag & BONE_TRANSFORM)) {
- calc_tw_center_with_matrix(tbounds, pchan->pose_head, use_mat_local, mat_local);
- protectflag_to_drawflags_pchan(rv3d, pchan, orient_index);
- }
+ /* Use channels to get stats. */
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
+ if (!(pchan->bone->flag & BONE_TRANSFORM)) {
+ continue;
}
- totsel += totsel_iter;
+ calc_tw_center_with_matrix(tbounds, pchan->pose_head, use_mat_local, mat_local);
+ protectflag_to_drawflags_pchan(rv3d, pchan, orient_index);
+ totsel++;
}
}
MEM_freeN(objects);
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index 0320a2a9a1a..e86392e47ab 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -47,6 +47,8 @@
#include "DEG_depsgraph.h"
+#include "DNA_gpencil_types.h"
+
#include "ED_armature.h"
#include "ED_asset.h"
#include "ED_image.h"
@@ -117,6 +119,10 @@ void ED_editors_init(bContext *C)
/* For multi-edit mode we may already have mode data (grease pencil does not need it).
* However we may have a non-active object stuck in a grease-pencil edit mode. */
if (ob != obact) {
+ bGPdata *gpd = (bGPdata *)ob->data;
+ gpd->flag &= ~(GP_DATA_STROKE_PAINTMODE | GP_DATA_STROKE_EDITMODE |
+ GP_DATA_STROKE_SCULPTMODE | GP_DATA_STROKE_WEIGHTMODE |
+ GP_DATA_STROKE_VERTEXMODE);
ob->mode = OB_MODE_OBJECT;
DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
}
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index 972758febd4..05c992274eb 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -71,6 +71,8 @@ GPUShader *GPU_shader_create_ex(const char *vertcode,
GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info);
GPUShader *GPU_shader_create_from_info_name(const char *info_name);
+const GPUShaderCreateInfo *GPU_shader_create_info_get(const char *info_name);
+
struct GPU_ShaderCreateFromArray_Params {
const char **vert, **geom, **frag, **defs;
};
diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc
index ef800abc3c9..2e924925ab8 100644
--- a/source/blender/gpu/intern/gpu_shader.cc
+++ b/source/blender/gpu/intern/gpu_shader.cc
@@ -249,6 +249,11 @@ GPUShader *GPU_shader_create_compute(const char *computecode,
shname);
}
+const GPUShaderCreateInfo *GPU_shader_create_info_get(const char *info_name)
+{
+ return gpu_shader_create_info_get(info_name);
+}
+
GPUShader *GPU_shader_create_from_info_name(const char *info_name)
{
using namespace blender::gpu::shader;
@@ -309,9 +314,8 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
}
if (!info.vertex_source_.is_empty()) {
- uint32_t builtins = 0;
+ char *code = gpu_shader_dependency_get_resolved_source(info.vertex_source_.c_str());
std::string interface = shader->vertex_interface_declare(info);
- char *code = gpu_shader_dependency_get_resolved_source(info.vertex_source_.c_str(), &builtins);
Vector<const char *> sources;
standard_defines(sources);
@@ -336,10 +340,8 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
}
if (!info.fragment_source_.is_empty()) {
- uint32_t builtins = 0;
+ char *code = gpu_shader_dependency_get_resolved_source(info.fragment_source_.c_str());
std::string interface = shader->fragment_interface_declare(info);
- char *code = gpu_shader_dependency_get_resolved_source(info.fragment_source_.c_str(),
- &builtins);
Vector<const char *> sources;
standard_defines(sources);
@@ -364,11 +366,9 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
}
if (!info.geometry_source_.is_empty()) {
- uint32_t builtins = 0;
- std::string interface = shader->geometry_interface_declare(info);
+ char *code = gpu_shader_dependency_get_resolved_source(info.geometry_source_.c_str());
std::string layout = shader->geometry_layout_declare(info);
- char *code = gpu_shader_dependency_get_resolved_source(info.geometry_source_.c_str(),
- &builtins);
+ std::string interface = shader->geometry_interface_declare(info);
Vector<const char *> sources;
standard_defines(sources);
@@ -391,9 +391,7 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
}
if (!info.compute_source_.is_empty()) {
- uint32_t builtins = 0;
- char *code = gpu_shader_dependency_get_resolved_source(info.compute_source_.c_str(),
- &builtins);
+ char *code = gpu_shader_dependency_get_resolved_source(info.compute_source_.c_str());
std::string layout = shader->compute_layout_declare(info);
Vector<const char *> sources;
diff --git a/source/blender/gpu/intern/gpu_shader_create_info.cc b/source/blender/gpu/intern/gpu_shader_create_info.cc
index 252708bc96a..1464a7ade24 100644
--- a/source/blender/gpu/intern/gpu_shader_create_info.cc
+++ b/source/blender/gpu/intern/gpu_shader_create_info.cc
@@ -34,6 +34,7 @@
#include "gpu_shader_create_info.hh"
#include "gpu_shader_create_info_private.hh"
+#include "gpu_shader_dependency_private.h"
#include "gpu_shader_private.hh"
#undef GPU_SHADER_INTERFACE_INFO
@@ -209,6 +210,19 @@ void gpu_shader_create_info_init()
draw_modelmat = draw_modelmat_legacy;
}
+ for (ShaderCreateInfo *info : g_create_infos->values()) {
+ if (info->do_static_compilation_) {
+ info->builtins_ |= static_cast<BuiltinBits>(
+ gpu_shader_dependency_get_builtins(info->vertex_source_.c_str()));
+ info->builtins_ |= static_cast<BuiltinBits>(
+ gpu_shader_dependency_get_builtins(info->fragment_source_.c_str()));
+ info->builtins_ |= static_cast<BuiltinBits>(
+ gpu_shader_dependency_get_builtins(info->geometry_source_.c_str()));
+ info->builtins_ |= static_cast<BuiltinBits>(
+ gpu_shader_dependency_get_builtins(info->compute_source_.c_str()));
+ }
+ }
+
/* TEST */
// gpu_shader_create_info_compile_all();
}
@@ -302,6 +316,7 @@ const GPUShaderCreateInfo *gpu_shader_create_info_get(const char *info_name)
{
if (g_create_infos->contains(info_name) == false) {
printf("Error: Cannot find shader create info named \"%s\"\n", info_name);
+ return nullptr;
}
ShaderCreateInfo *info = g_create_infos->lookup(info_name);
return reinterpret_cast<const GPUShaderCreateInfo *>(info);
diff --git a/source/blender/gpu/intern/gpu_shader_create_info.hh b/source/blender/gpu/intern/gpu_shader_create_info.hh
index 63c6e94f4c8..736a8ed0590 100644
--- a/source/blender/gpu/intern/gpu_shader_create_info.hh
+++ b/source/blender/gpu/intern/gpu_shader_create_info.hh
@@ -63,6 +63,7 @@ enum class Type {
};
enum class BuiltinBits {
+ NONE = 0,
/**
* Allow getting barycentric coordinates inside the fragment shader.
* \note Emulated on OpenGL.
@@ -72,6 +73,10 @@ enum class BuiltinBits {
FRONT_FACING = (1 << 4),
GLOBAL_INVOCATION_ID = (1 << 5),
INSTANCE_ID = (1 << 6),
+ /**
+ * Allow setting the target layer when the output is a layered framebuffer.
+ * \note Emulated through geometry shader on older hardware.
+ */
LAYER = (1 << 7),
LOCAL_INVOCATION_ID = (1 << 8),
LOCAL_INVOCATION_INDEX = (1 << 9),
@@ -125,10 +130,13 @@ enum class ImageType {
/* Storage qualifiers. */
enum class Qualifier {
- RESTRICT = (1 << 0),
- READ_ONLY = (1 << 1),
- WRITE_ONLY = (1 << 2),
- QUALIFIER_MAX = (WRITE_ONLY << 1) - 1,
+ /** Restrict flag is set by default. Unless specified otherwise. */
+ NO_RESTRICT = (1 << 0),
+ READ = (1 << 1),
+ WRITE = (1 << 2),
+ /** Shorthand version of combined flags. */
+ READ_WRITE = READ | WRITE,
+ QUALIFIER_MAX = (WRITE << 1) - 1,
};
ENUM_OPERATORS(Qualifier, Qualifier::QUALIFIER_MAX);
@@ -226,6 +234,8 @@ struct ShaderCreateInfo {
* Only for names used by gpu::ShaderInterface.
*/
size_t interface_names_size_ = 0;
+ /** Manually set builtins. */
+ BuiltinBits builtins_ = BuiltinBits::NONE;
struct VertIn {
int index;
@@ -538,6 +548,12 @@ struct ShaderCreateInfo {
return *(Self *)this;
}
+ Self &builtins(BuiltinBits builtin)
+ {
+ builtins_ |= builtin;
+ return *(Self *)this;
+ }
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/gpu/intern/gpu_shader_dependency.cc b/source/blender/gpu/intern/gpu_shader_dependency.cc
index 5e03f7d0767..0db03c2b636 100644
--- a/source/blender/gpu/intern/gpu_shader_dependency.cc
+++ b/source/blender/gpu/intern/gpu_shader_dependency.cc
@@ -59,7 +59,6 @@ struct GPUSource {
/* Scan for builtins. */
/* FIXME: This can trigger false positive caused by disabled #if blocks. */
/* TODO(fclem): Could be made faster by scanning once. */
- /* TODO(fclem): BARYCENTRIC_COORD. */
if (source.find("gl_FragCoord", 0)) {
builtins |= shader::BuiltinBits::FRAG_COORD;
}
@@ -72,9 +71,6 @@ struct GPUSource {
if (source.find("gl_InstanceID", 0)) {
builtins |= shader::BuiltinBits::INSTANCE_ID;
}
- if (source.find("gl_Layer", 0)) {
- builtins |= shader::BuiltinBits::LAYER;
- }
if (source.find("gl_LocalInvocationID", 0)) {
builtins |= shader::BuiltinBits::LOCAL_INVOCATION_ID;
}
@@ -336,13 +332,23 @@ struct GPUSource {
}
/* Returns the final string with all includes done. */
- void build(std::string &str, shader::BuiltinBits &out_builtins)
+ std::string build() const
{
+ std::string str;
for (auto *dep : dependencies) {
- out_builtins |= builtins;
str += dep->source;
}
str += source;
+ return str;
+ }
+
+ shader::BuiltinBits builtins_get() const
+ {
+ shader::BuiltinBits out_builtins = shader::BuiltinBits::NONE;
+ for (auto *dep : dependencies) {
+ out_builtins |= dep->builtins;
+ }
+ return out_builtins;
}
};
@@ -377,14 +383,19 @@ void gpu_shader_dependency_exit()
delete g_sources;
}
-char *gpu_shader_dependency_get_resolved_source(const char *shader_source_name, uint32_t *builtins)
+uint32_t gpu_shader_dependency_get_builtins(const char *shader_source_name)
+{
+ if (shader_source_name[0] == '\0') {
+ return 0;
+ }
+ GPUSource *source = g_sources->lookup(shader_source_name);
+ return static_cast<uint32_t>(source->builtins_get());
+}
+
+char *gpu_shader_dependency_get_resolved_source(const char *shader_source_name)
{
GPUSource *source = g_sources->lookup(shader_source_name);
- std::string str;
- shader::BuiltinBits out_builtins;
- source->build(str, out_builtins);
- *builtins |= (uint32_t)out_builtins;
- return strdup(str.c_str());
+ return strdup(source->build().c_str());
}
char *gpu_shader_dependency_get_source(const char *shader_source_name)
diff --git a/source/blender/gpu/intern/gpu_shader_dependency_private.h b/source/blender/gpu/intern/gpu_shader_dependency_private.h
index b129ca74a48..083c38897ce 100644
--- a/source/blender/gpu/intern/gpu_shader_dependency_private.h
+++ b/source/blender/gpu/intern/gpu_shader_dependency_private.h
@@ -35,10 +35,11 @@ void gpu_shader_dependency_init(void);
void gpu_shader_dependency_exit(void);
/* User must free the resulting string using free. */
-char *gpu_shader_dependency_get_resolved_source(const char *shader_source_name,
- uint32_t *builtins);
+char *gpu_shader_dependency_get_resolved_source(const char *shader_source_name);
char *gpu_shader_dependency_get_source(const char *shader_source_name);
+uint32_t gpu_shader_dependency_get_builtins(const char *shader_source_name);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc
index 92d180f1140..2ee7c0503f4 100644
--- a/source/blender/gpu/opengl/gl_backend.cc
+++ b/source/blender/gpu/opengl/gl_backend.cc
@@ -248,6 +248,8 @@ static void detect_workarounds()
GLContext::direct_state_access_support = false;
GLContext::fixed_restart_index_support = false;
GLContext::geometry_shader_invocations = false;
+ GLContext::layered_rendering_support = false;
+ GLContext::native_barycentric_support = false;
GLContext::multi_bind_support = false;
GLContext::multi_draw_indirect_support = false;
GLContext::shader_draw_parameters_support = false;
@@ -445,6 +447,8 @@ bool GLContext::direct_state_access_support = false;
bool GLContext::explicit_location_support = false;
bool GLContext::geometry_shader_invocations = false;
bool GLContext::fixed_restart_index_support = false;
+bool GLContext::layered_rendering_support = false;
+bool GLContext::native_barycentric_support = false;
bool GLContext::multi_bind_support = false;
bool GLContext::multi_draw_indirect_support = false;
bool GLContext::shader_draw_parameters_support = false;
@@ -505,6 +509,8 @@ void GLBackend::capabilities_init()
GLContext::explicit_location_support = GLEW_VERSION_4_3;
GLContext::geometry_shader_invocations = GLEW_ARB_gpu_shader5;
GLContext::fixed_restart_index_support = GLEW_ARB_ES3_compatibility;
+ GLContext::layered_rendering_support = GLEW_AMD_vertex_shader_layer;
+ GLContext::native_barycentric_support = GLEW_AMD_shader_explicit_vertex_parameter;
GLContext::multi_bind_support = GLEW_ARB_multi_bind;
GLContext::multi_draw_indirect_support = GLEW_ARB_multi_draw_indirect;
GLContext::shader_draw_parameters_support = GLEW_ARB_shader_draw_parameters;
diff --git a/source/blender/gpu/opengl/gl_context.hh b/source/blender/gpu/opengl/gl_context.hh
index dd22418972b..b7a74863ac4 100644
--- a/source/blender/gpu/opengl/gl_context.hh
+++ b/source/blender/gpu/opengl/gl_context.hh
@@ -72,6 +72,8 @@ class GLContext : public Context {
static bool explicit_location_support;
static bool geometry_shader_invocations;
static bool fixed_restart_index_support;
+ static bool layered_rendering_support;
+ static bool native_barycentric_support;
static bool multi_bind_support;
static bool multi_draw_indirect_support;
static bool shader_draw_parameters_support;
diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc
index 810d07e6ef1..3ab3b11d1f4 100644
--- a/source/blender/gpu/opengl/gl_shader.cc
+++ b/source/blender/gpu/opengl/gl_shader.cc
@@ -277,15 +277,15 @@ static void print_image_type(std::ostream &os,
static std::ostream &print_qualifier(std::ostream &os, const Qualifier &qualifiers)
{
- if ((qualifiers & Qualifier::RESTRICT) == Qualifier::RESTRICT) {
+ if (bool(qualifiers & Qualifier::NO_RESTRICT) == false) {
os << "restrict ";
}
- if ((qualifiers & Qualifier::READ_ONLY) == Qualifier::READ_ONLY) {
- os << "readonly ";
- }
- if ((qualifiers & Qualifier::WRITE_ONLY) == Qualifier::WRITE_ONLY) {
+ if (bool(qualifiers & Qualifier::READ) == false) {
os << "writeonly ";
}
+ if (bool(qualifiers & Qualifier::WRITE) == false) {
+ os << "readonly ";
+ }
return os;
}
@@ -415,11 +415,31 @@ std::string GLShader::resources_declare(const ShaderCreateInfo &info) const
}
ss << ";\n";
}
+#if 0 /* T95278: This is not be enough to prevent some compilers think it is recursive. */
for (const ShaderCreateInfo::PushConst &uniform : info.push_constants_) {
/* T95278: Double macro to avoid some compilers think it is recursive. */
ss << "#define " << uniform.name << "_ " << uniform.name << "\n";
ss << "#define " << uniform.name << " (" << uniform.name << "_)\n";
}
+#endif
+ ss << "\n";
+ return ss.str();
+}
+
+static std::string main_function_wrapper(std::string &pre_main, std::string &post_main)
+{
+ std::stringstream ss;
+ /* Prototype for the original main. */
+ ss << "\n";
+ ss << "void main_function_();\n";
+ /* Wrapper to the main function in order to inject code processing on globals. */
+ ss << "void main() {\n";
+ ss << pre_main;
+ ss << " main_function_();\n";
+ ss << post_main;
+ ss << "}\n";
+ /* Rename the original main. */
+ ss << "#define main main_function_\n";
ss << "\n";
return ss.str();
}
@@ -427,6 +447,7 @@ std::string GLShader::resources_declare(const ShaderCreateInfo &info) const
std::string GLShader::vertex_interface_declare(const ShaderCreateInfo &info) const
{
std::stringstream ss;
+ std::string post_main = "";
ss << "\n/* Inputs. */\n";
for (const ShaderCreateInfo::VertIn &attr : info.vertex_inputs_) {
@@ -439,13 +460,35 @@ std::string GLShader::vertex_interface_declare(const ShaderCreateInfo &info) con
for (const StageInterfaceInfo *iface : info.vertex_out_interfaces_) {
print_interface(ss, "out", *iface);
}
+ if (!GLContext::layered_rendering_support && bool(info.builtins_ & BuiltinBits::LAYER)) {
+ ss << "out int gpu_Layer;\n";
+ }
+ if (bool(info.builtins_ & BuiltinBits::BARYCENTRIC_COORD)) {
+ if (!GLContext::native_barycentric_support) {
+ /* Disabled or unsupported. */
+ }
+ else if (GLEW_AMD_shader_explicit_vertex_parameter) {
+ /* Need this for stable barycentric. */
+ ss << "flat out vec4 gpu_pos_flat;\n";
+ ss << "out vec4 gpu_pos;\n";
+
+ post_main += " gpu_pos = gpu_pos_flat = gl_Position;\n";
+ }
+ }
ss << "\n";
+
+ if (post_main.empty() == false) {
+ std::string pre_main = "";
+ ss << main_function_wrapper(pre_main, post_main);
+ }
return ss.str();
}
std::string GLShader::fragment_interface_declare(const ShaderCreateInfo &info) const
{
std::stringstream ss;
+ std::string pre_main = "";
+
ss << "\n/* Interfaces. */\n";
const Vector<StageInterfaceInfo *> &in_interfaces = (info.geometry_source_.is_empty()) ?
info.vertex_out_interfaces_ :
@@ -453,6 +496,32 @@ std::string GLShader::fragment_interface_declare(const ShaderCreateInfo &info) c
for (const StageInterfaceInfo *iface : in_interfaces) {
print_interface(ss, "in", *iface);
}
+ if (bool(info.builtins_ & BuiltinBits::BARYCENTRIC_COORD)) {
+ if (!GLContext::native_barycentric_support) {
+ ss << "smooth in vec3 gpu_BaryCoord;\n";
+ ss << "noperspective in vec3 gpu_BaryCoordNoPersp;\n";
+ }
+ else if (GLEW_AMD_shader_explicit_vertex_parameter) {
+ /* NOTE(fclem): This won't work with geometry shader. Hopefully, we don't need geometry
+ * shader workaround if this extension/feature is detected. */
+ ss << "\n/* Stable Barycentric Coordinates. */\n";
+ ss << "flat in vec4 gpu_pos_flat;\n";
+ ss << "__explicitInterpAMD in vec4 gpu_pos;\n";
+ /* Globals. */
+ ss << "vec3 gpu_BaryCoord;\n";
+ ss << "vec3 gpu_BaryCoordNoPersp;\n";
+ ss << "\n";
+ ss << "vec2 stable_bary_(vec2 in_bary) {\n";
+ ss << " vec3 bary = vec3(in_bary, 1.0 - in_bary.x - in_bary.y);\n";
+ ss << " if (interpolateAtVertexAMD(gpu_pos, 0) == gpu_pos_flat) { return bary.zxy; }\n";
+ ss << " if (interpolateAtVertexAMD(gpu_pos, 2) == gpu_pos_flat) { return bary.yzx; }\n";
+ ss << " return bary.xyz;\n";
+ ss << "}\n";
+
+ pre_main += " gpu_BaryCoord = stable_bary_(gl_BaryCoordSmoothAMD);\n";
+ pre_main += " gpu_BaryCoordNoPersp = stable_bary_(gl_BaryCoordNoPerspAMD);\n";
+ }
+ }
ss << "\n/* Outputs. */\n";
for (const ShaderCreateInfo::FragOut &output : info.fragment_outputs_) {
ss << "layout(location = " << output.index;
@@ -470,6 +539,11 @@ std::string GLShader::fragment_interface_declare(const ShaderCreateInfo &info) c
ss << "out " << to_string(output.type) << " " << output.name << ";\n";
}
ss << "\n";
+
+ if (pre_main.empty() == false) {
+ std::string post_main = "";
+ ss << main_function_wrapper(pre_main, post_main);
+ }
return ss.str();
}
@@ -501,7 +575,7 @@ static StageInterfaceInfo *find_interface_by_name(const Vector<StageInterfaceInf
const StringRefNull &name)
{
for (auto *iface : ifaces) {
- if (iface->name == name) {
+ if (iface->instance_name == name) {
return iface;
}
}
@@ -510,8 +584,8 @@ static StageInterfaceInfo *find_interface_by_name(const Vector<StageInterfaceInf
std::string GLShader::geometry_interface_declare(const ShaderCreateInfo &info) const
{
-
std::stringstream ss;
+
ss << "\n/* Interfaces. */\n";
for (const StageInterfaceInfo *iface : info.vertex_out_interfaces_) {
bool has_matching_output_iface = find_interface_by_name(info.geometry_out_interfaces_,
@@ -545,6 +619,76 @@ std::string GLShader::compute_layout_declare(const ShaderCreateInfo &info) const
ss << "\n";
return ss.str();
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Passthrough geometry shader emulation
+ *
+ * \{ */
+
+std::string GLShader::workaround_geometry_shader_source_create(
+ const shader::ShaderCreateInfo &info)
+{
+ std::stringstream ss;
+
+ const bool do_layer_workaround = !GLContext::layered_rendering_support &&
+ bool(info.builtins_ & BuiltinBits::LAYER);
+ const bool do_barycentric_workaround = !GLContext::native_barycentric_support &&
+ bool(info.builtins_ & BuiltinBits::BARYCENTRIC_COORD);
+
+ shader::ShaderCreateInfo info_modified = info;
+ info_modified.geometry_out_interfaces_ = info_modified.vertex_out_interfaces_;
+ /**
+ * NOTE(@fclem): Assuming we will render TRIANGLES. This will not work with other primitive
+ * types. In this case, it might not trigger an error on some implementations.
+ */
+ info_modified.geometry_layout(PrimitiveIn::TRIANGLES, PrimitiveOut::TRIANGLE_STRIP, 3);
+
+ ss << geometry_layout_declare(info_modified);
+ ss << geometry_interface_declare(info_modified);
+ if (do_layer_workaround) {
+ ss << "in int gpu_Layer[];\n";
+ }
+ if (do_barycentric_workaround) {
+ ss << "smooth out vec3 gpu_BaryCoord;\n";
+ ss << "noperspective out vec3 gpu_BaryCoordNoPersp;\n";
+ }
+ ss << "\n";
+
+ ss << "void main()\n";
+ ss << "{\n";
+ if (do_layer_workaround) {
+ ss << " gl_Layer = gpu_Layer[0];\n";
+ }
+ for (auto i : IndexRange(3)) {
+ for (auto iface : info_modified.vertex_out_interfaces_) {
+ for (auto &inout : iface->inouts) {
+ ss << " " << iface->instance_name << "_out." << inout.name;
+ ss << " = " << iface->instance_name << "_in[" << i << "]." << inout.name << ";\n";
+ }
+ }
+ if (do_barycentric_workaround) {
+ ss << " gpu_BaryCoordNoPersp = gpu_BaryCoord =";
+ ss << " vec3(" << int(i == 0) << ", " << int(i == 1) << ", " << int(i == 2) << ");\n";
+ }
+ ss << " gl_Position = gl_in[" << i << "].gl_Position;\n";
+ ss << " EmitVertex();\n";
+ }
+ ss << "}\n";
+ return ss.str();
+}
+
+bool GLShader::do_geometry_shader_injection(const shader::ShaderCreateInfo *info)
+{
+ BuiltinBits builtins = info->builtins_;
+ if (!GLContext::native_barycentric_support && bool(builtins & BuiltinBits::BARYCENTRIC_COORD)) {
+ return true;
+ }
+ if (!GLContext::layered_rendering_support && bool(builtins & BuiltinBits::LAYER)) {
+ return true;
+ }
+ return false;
+}
/** \} */
@@ -555,7 +699,7 @@ std::string GLShader::compute_layout_declare(const ShaderCreateInfo &info) const
static char *glsl_patch_default_get()
{
/** Used for shader patching. Init once. */
- static char patch[700] = "\0";
+ static char patch[1024] = "\0";
if (patch[0] != '\0') {
return patch;
}
@@ -599,6 +743,13 @@ static char *glsl_patch_default_get()
STR_CONCAT(patch, slen, "#extension GL_ARB_shader_image_load_store: enable\n");
STR_CONCAT(patch, slen, "#extension GL_ARB_shading_language_420pack: enable\n");
}
+ if (GLContext::layered_rendering_support) {
+ STR_CONCAT(patch, slen, "#extension GL_AMD_vertex_shader_layer: enable\n");
+ STR_CONCAT(patch, slen, "#define gpu_Layer gl_Layer\n");
+ }
+ if (GLContext::native_barycentric_support) {
+ STR_CONCAT(patch, slen, "#extension GL_AMD_shader_explicit_vertex_parameter: enable\n");
+ }
/* Fallbacks. */
if (!GLContext::shader_draw_parameters_support) {
@@ -715,6 +866,14 @@ bool GLShader::finalize(const shader::ShaderCreateInfo *info)
return false;
}
+ if (info && do_geometry_shader_injection(info)) {
+ std::string source = workaround_geometry_shader_source_create(*info);
+ Vector<const char *> sources;
+ sources.append("version");
+ sources.append(source.c_str());
+ geometry_shader_from_glsl(sources);
+ }
+
glLinkProgram(shader_program_);
GLint status;
diff --git a/source/blender/gpu/opengl/gl_shader.hh b/source/blender/gpu/opengl/gl_shader.hh
index a82ab026c16..cc1c93142f8 100644
--- a/source/blender/gpu/opengl/gl_shader.hh
+++ b/source/blender/gpu/opengl/gl_shader.hh
@@ -94,6 +94,14 @@ class GLShader : public Shader {
/** Create, compile and attach the shader stage to the shader program. */
GLuint create_shader_stage(GLenum gl_stage, MutableSpan<const char *> sources);
+ /**
+ * \brief features available on newer implementation such as native barycentric coordinates
+ * and layered rendering, necessitate a geometry shader to work on older hardware.
+ */
+ std::string workaround_geometry_shader_source_create(const shader::ShaderCreateInfo &info);
+
+ bool do_geometry_shader_injection(const shader::ShaderCreateInfo *info);
+
MEM_CXX_CLASS_ALLOC_FUNCS("GLShader");
};
diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c
index a85ba65d014..00e96e7840b 100644
--- a/source/blender/imbuf/intern/indexer.c
+++ b/source/blender/imbuf/intern/indexer.c
@@ -247,8 +247,10 @@ struct anim_index *IMB_indexer_open(const char *name)
uint64_t IMB_indexer_get_seek_pos(struct anim_index *idx, int frame_index)
{
- if (frame_index < 0) {
- frame_index = 0;
+ /* This is hard coded, because our current timecode files return non zero seek position for index
+ * 0. Only when seeking to 0 it is guaranteed, that first packet will be read. */
+ if (frame_index <= 0) {
+ return 0;
}
if (frame_index >= idx->num_entries) {
frame_index = idx->num_entries - 1;
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 1d76e2ea248..e18629c9746 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -10531,7 +10531,7 @@ static void def_geo_object_info(StructRNA *srna)
RNA_def_property_enum_items(prop, rna_node_geometry_object_info_transform_space_items);
RNA_def_property_ui_text(
prop, "Transform Space", "The transformation of the vector and geometry outputs");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update_relations");
}
static void def_geo_legacy_points_to_volume(StructRNA *srna)
@@ -10615,7 +10615,7 @@ static void def_geo_collection_info(StructRNA *srna)
prop = RNA_def_property(srna, "transform_space", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_node_geometry_collection_info_transform_space_items);
RNA_def_property_ui_text(prop, "Transform Space", "The transformation of the geometry output");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update_relations");
}
static void def_geo_legacy_attribute_proximity(StructRNA *srna)
diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc
index 24a8a9621c5..0d5a9a9e609 100644
--- a/source/blender/modifiers/intern/MOD_nodes.cc
+++ b/source/blender/modifiers/intern/MOD_nodes.cc
@@ -177,7 +177,32 @@ static void add_used_ids_from_sockets(const ListBase &sockets, Set<ID *> &ids)
}
}
-static void find_used_ids_from_nodes(const bNodeTree &tree, Set<ID *> &ids)
+/**
+ * \note We can only check properties here that cause the dependency graph to update relations when
+ * they are changed, otherwise there may be a missing relation after editing. So this could check
+ * more properties like whether the node is muted, but we would have to accept the cost of updating
+ * relations when those properties are changed.
+ */
+static bool node_needs_own_transform_relation(const bNode &node)
+{
+ if (node.type == GEO_NODE_COLLECTION_INFO) {
+ const NodeGeometryCollectionInfo &storage = *static_cast<const NodeGeometryCollectionInfo *>(
+ node.storage);
+ return storage.transform_space == GEO_NODE_TRANSFORM_SPACE_RELATIVE;
+ }
+
+ if (node.type == GEO_NODE_OBJECT_INFO) {
+ const NodeGeometryObjectInfo &storage = *static_cast<const NodeGeometryObjectInfo *>(
+ node.storage);
+ return storage.transform_space == GEO_NODE_TRANSFORM_SPACE_RELATIVE;
+ }
+
+ return false;
+}
+
+static void process_nodes_for_depsgraph(const bNodeTree &tree,
+ Set<ID *> &ids,
+ bool &needs_own_transform_relation)
{
Set<const bNodeTree *> handled_groups;
@@ -188,9 +213,10 @@ static void find_used_ids_from_nodes(const bNodeTree &tree, Set<ID *> &ids)
if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP)) {
const bNodeTree *group = (bNodeTree *)node->id;
if (group != nullptr && handled_groups.add(group)) {
- find_used_ids_from_nodes(*group, ids);
+ process_nodes_for_depsgraph(*group, ids, needs_own_transform_relation);
}
}
+ needs_own_transform_relation |= node_needs_own_transform_relation(*node);
}
}
@@ -244,12 +270,12 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
return;
}
- DEG_add_modifier_to_transform_relation(ctx->node, "Nodes Modifier");
DEG_add_node_tree_output_relation(ctx->node, nmd->node_group, "Nodes Modifier");
+ bool needs_own_transform_relation = false;
Set<ID *> used_ids;
find_used_ids_from_settings(nmd->settings, used_ids);
- find_used_ids_from_nodes(*nmd->node_group, used_ids);
+ process_nodes_for_depsgraph(*nmd->node_group, used_ids, needs_own_transform_relation);
for (ID *id : used_ids) {
switch ((ID_Type)GS(id->name)) {
case ID_OB: {
@@ -273,6 +299,10 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
}
}
}
+
+ if (needs_own_transform_relation) {
+ DEG_add_modifier_to_transform_relation(ctx->node, "Nodes Modifier");
+ }
}
static bool check_tree_for_time_node(const bNodeTree &tree,