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:
authorFalk David <falkdavid@gmx.de>2022-02-07 14:13:22 +0300
committerFalk David <falkdavid@gmx.de>2022-02-07 14:13:22 +0300
commitc3ac35d6e73ded3a45b392336c337abaf6b64a13 (patch)
treef81727fdce68da25db741120818ea49a93c7b7cd /source/blender
parenta59861518262b19c8d5f352429c96c304e349638 (diff)
parent463828a7a840b7ae38b2b62637826b71d14b5a80 (diff)
Merge branch 'patch/gpencil-update-on-write' into patch/gpencil-undo-system
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blendthumb/CMakeLists.txt1
-rw-r--r--source/blender/blenfont/BLF_api.h2
-rw-r--r--source/blender/blenfont/intern/blf_default.c6
-rw-r--r--source/blender/blenfont/intern/blf_font.c59
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c49
-rw-r--r--source/blender/blenfont/intern/blf_internal.h20
-rw-r--r--source/blender/blenfont/intern/blf_internal_types.h6
-rw-r--r--source/blender/blenfont/intern/blf_thumbs.c7
-rw-r--r--source/blender/blenkernel/BKE_attribute_math.hh26
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.cc7
-rw-r--r--source/blender/blenkernel/intern/attribute_access.cc17
-rw-r--r--source/blender/blenkernel/intern/attribute_access_intern.hh3
-rw-r--r--source/blender/blenkernel/intern/customdata.cc6
-rw-r--r--source/blender/blenkernel/intern/mesh.cc11
-rw-r--r--source/blender/blenkernel/intern/node.cc17
-rw-r--r--source/blender/blenkernel/intern/type_conversions.cc64
-rw-r--r--source/blender/blenlib/BLI_enumerable_thread_specific.hh2
-rw-r--r--source/blender/blenlib/BLI_string_ref.hh3
-rw-r--r--source/blender/blenloader/intern/versioning_300.c17
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c144
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc2
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc4
-rw-r--r--source/blender/draw/engines/image/image_drawing_mode.hh2
-rw-r--r--source/blender/draw/engines/overlay/overlay_armature.c6
-rw-r--r--source/blender/draw/engines/overlay/overlay_fade.c1
-rw-r--r--source/blender/draw/engines/overlay/overlay_volume.c1
-rw-r--r--source/blender/draw/engines/overlay/shaders/edit_uv_edges_frag.glsl2
-rw-r--r--source/blender/draw/engines/workbench/shaders/infos/workbench_composite_info.hh2
-rw-r--r--source/blender/draw/engines/workbench/workbench_engine.c33
-rw-r--r--source/blender/draw/engines/workbench/workbench_shader_shared.h2
-rw-r--r--source/blender/draw/intern/DRW_gpu_wrapper.hh16
-rw-r--r--source/blender/draw/intern/DRW_render.h59
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c4
-rw-r--r--source/blender/draw/intern/draw_manager.h18
-rw-r--r--source/blender/draw/intern/draw_manager_data.c93
-rw-r--r--source/blender/draw/intern/draw_manager_exec.c14
-rw-r--r--source/blender/draw/intern/draw_shader_shared.h2
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc9
-rw-r--r--source/blender/draw/intern/shaders/common_view_lib.glsl10
-rw-r--r--source/blender/draw/intern/shaders/draw_view_info.hh2
-rw-r--r--source/blender/editors/gpencil/gpencil_sculpt_paint.c4
-rw-r--r--source/blender/editors/interface/interface_ops.c5
-rw-r--r--source/blender/editors/interface/interface_style.c13
-rw-r--r--source/blender/editors/render/render_internal.cc4
-rw-r--r--source/blender/editors/render/render_preview.cc2
-rw-r--r--source/blender/editors/space_graph/graph_slider_ops.c2
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_layout.cc22
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc2
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c1
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate.c49
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate.h14
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_dolly.c30
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_fly.c6
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_move.c21
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_ndof.c17
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_roll.c22
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_rotate.c22
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_walk.c6
-rw-r--r--source/blender/editors/space_view3d/view3d_navigate_zoom.c25
-rw-r--r--source/blender/functions/FN_field.hh5
-rw-r--r--source/blender/functions/intern/cpp_types.cc2
-rw-r--r--source/blender/functions/intern/field.cc13
-rw-r--r--source/blender/gpu/CMakeLists.txt2
-rw-r--r--source/blender/gpu/GPU_debug.h2
-rw-r--r--source/blender/gpu/GPU_shader_shared.h2
-rw-r--r--source/blender/gpu/GPU_shader_shared_utils.h (renamed from source/blender/gpu/intern/gpu_shader_shared_utils.h)0
-rw-r--r--source/blender/gpu/GPU_state.h13
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer_private.hh5
-rw-r--r--source/blender/gpu/intern/gpu_shader.cc83
-rw-r--r--source/blender/gpu/intern/gpu_shader_create_info.cc88
-rw-r--r--source/blender/gpu/intern/gpu_shader_create_info.hh226
-rw-r--r--source/blender/gpu/intern/gpu_shader_dependency.cc48
-rw-r--r--source/blender/gpu/intern/gpu_shader_dependency_private.h32
-rw-r--r--source/blender/gpu/intern/gpu_shader_interface.hh1
-rw-r--r--source/blender/gpu/intern/gpu_shader_log.cc108
-rw-r--r--source/blender/gpu/intern/gpu_shader_private.hh1
-rw-r--r--source/blender/gpu/intern/gpu_texture_private.hh18
-rw-r--r--source/blender/gpu/opengl/gl_compute.cc2
-rw-r--r--source/blender/gpu/opengl/gl_debug.cc10
-rw-r--r--source/blender/gpu/opengl/gl_debug_layer.cc4
-rw-r--r--source/blender/gpu/opengl/gl_framebuffer.hh2
-rw-r--r--source/blender/gpu/opengl/gl_shader.cc81
-rw-r--r--source/blender/gpu/opengl/gl_shader_interface.cc26
-rw-r--r--source/blender/gpu/opengl/gl_shader_log.cc9
-rw-r--r--source/blender/gpu/opengl/gl_state.hh13
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc238
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh24
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_io.hh10
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc4
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_nurbs.cc6
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_nurbs.hh4
-rw-r--r--source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc25
-rw-r--r--source/blender/makesdna/DNA_customdata_types.h10
-rw-r--r--source/blender/makesdna/DNA_meshdata_types.h3
-rw-r--r--source/blender/makesdna/DNA_node_types.h9
-rw-r--r--source/blender/makesdna/DNA_sequence_types.h7
-rw-r--r--source/blender/makesrna/RNA_access.h2
-rw-r--r--source/blender/makesrna/intern/rna_attribute.c60
-rw-r--r--source/blender/makesrna/intern/rna_sequencer.c13
-rw-r--r--source/blender/makesrna/intern/rna_space.c2
-rw-r--r--source/blender/modifiers/intern/MOD_nodes_evaluator.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc2
-rw-r--r--source/blender/render/intern/bake.c6
-rw-r--r--source/blender/render/intern/texture_margin.cc6
-rw-r--r--source/blender/sequencer/intern/render.c11
-rw-r--r--source/blender/sequencer/intern/sequencer.c1
107 files changed, 1641 insertions, 618 deletions
diff --git a/source/blender/blendthumb/CMakeLists.txt b/source/blender/blendthumb/CMakeLists.txt
index e2d278255ba..d64e942069d 100644
--- a/source/blender/blendthumb/CMakeLists.txt
+++ b/source/blender/blendthumb/CMakeLists.txt
@@ -65,6 +65,7 @@ else()
)
add_executable(blender-thumbnailer ${SRC} ${SRC_CMD})
+ setup_platform_linker_flags(blender-thumbnailer)
target_link_libraries(blender-thumbnailer bf_blenlib)
target_link_libraries(blender-thumbnailer ${PTHREADS_LIBRARIES})
endif()
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index 169107b19cb..638c5b727a6 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -309,7 +309,7 @@ void BLF_thumb_preview(const char *filename,
/* blf_default.c */
void BLF_default_dpi(int dpi);
-void BLF_default_size(int size);
+void BLF_default_size(float size);
void BLF_default_set(int fontid);
/**
* Get default font ID so we can pass it to other functions.
diff --git a/source/blender/blenfont/intern/blf_default.c b/source/blender/blenfont/intern/blf_default.c
index 57eeaa6768d..d5a0d514b5f 100644
--- a/source/blender/blenfont/intern/blf_default.c
+++ b/source/blender/blenfont/intern/blf_default.c
@@ -37,15 +37,15 @@
/* Default size and dpi, for BLF_draw_default. */
static int global_font_default = -1;
static int global_font_dpi = 72;
-/* Keep in sync with `UI_style_get()->widgetlabel.points` */
-static int global_font_size = 11;
+/* Keep in sync with `UI_DEFAULT_TEXT_POINTS` */
+static float global_font_size = 11.0f;
void BLF_default_dpi(int dpi)
{
global_font_dpi = dpi;
}
-void BLF_default_size(int size)
+void BLF_default_size(float size)
{
global_font_size = size;
}
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index 14d3a208f69..c1410447de6 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -34,7 +34,6 @@
#include FT_FREETYPE_H
#include FT_GLYPH_H
-#include FT_ADVANCES_H /* For FT_Get_Advance */
#include "MEM_guardedalloc.h"
@@ -826,7 +825,10 @@ float blf_font_height(FontBLF *font,
float blf_font_fixed_width(FontBLF *font)
{
- return (float)font->fixed_width;
+ GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
+ float width = (gc) ? (float)gc->fixed_width : font->size / 2.0f;
+ blf_glyph_cache_release(font);
+ return width;
}
static void blf_font_boundbox_foreach_glyph_ex(FontBLF *font,
@@ -1318,12 +1320,7 @@ FontBLF *blf_font_new_from_mem(const char *name, const unsigned char *mem, int m
void blf_font_free(FontBLF *font)
{
- BLI_spin_lock(&blf_glyph_cache_mutex);
- GlyphCacheBLF *gc;
-
- while ((gc = BLI_pophead(&font->cache))) {
- blf_glyph_cache_free(gc);
- }
+ blf_glyph_cache_clear(font);
if (font->kerning_cache) {
MEM_freeN(font->kerning_cache);
@@ -1337,8 +1334,6 @@ void blf_font_free(FontBLF *font)
MEM_freeN(font->name);
}
MEM_freeN(font);
-
- BLI_spin_unlock(&blf_glyph_cache_mutex);
}
/** \} */
@@ -1347,51 +1342,25 @@ void blf_font_free(FontBLF *font)
/** \name Font Configure
* \{ */
-void blf_font_size(FontBLF *font, float size, unsigned int dpi)
+bool blf_font_size(FontBLF *font, float size, unsigned int dpi)
{
- blf_glyph_cache_acquire(font);
-
/* FreeType uses fixed-point integers in 64ths. */
FT_F26Dot6 ft_size = lroundf(size * 64.0f);
- /* Adjust our size to be on even 64ths. */
+ /* Adjust our new size to be on even 64ths. */
size = (float)ft_size / 64.0f;
- GlyphCacheBLF *gc = blf_glyph_cache_find(font, size, dpi);
- if (gc && (font->size == size && font->dpi == dpi)) {
- /* Optimization: do not call FT_Set_Char_Size if size did not change. */
- }
- else {
- const FT_Error err = FT_Set_Char_Size(font->face, 0, ft_size, dpi, dpi);
- if (err) {
- /* FIXME: here we can go through the fixed size and choice a close one */
- printf("The current font don't support the size, %f and dpi, %u\n", size, dpi);
- }
- else {
+ if (font->size != size || font->dpi != dpi) {
+ if (FT_Set_Char_Size(font->face, 0, ft_size, dpi, dpi) == 0) {
font->size = size;
font->dpi = dpi;
- if (gc == NULL) {
- blf_glyph_cache_new(font);
- }
+ }
+ else {
+ printf("The current font does not support the size, %f and dpi, %u\n", size, dpi);
+ return false;
}
}
- blf_glyph_cache_release(font);
-
- /* Set fixed-width size for monospaced output. */
- FT_UInt gindex = FT_Get_Char_Index(font->face, U'0');
- if (gindex) {
- FT_Fixed advance = 0;
- FT_Get_Advance(font->face, gindex, FT_LOAD_NO_HINTING, &advance);
- /* Use CSS 'ch unit' width, advance of zero character. */
- font->fixed_width = (int)(advance >> 16);
- }
- else {
- /* Font does not contain "0" so use CSS fallback of 1/2 of em. */
- font->fixed_width = (int)((font->face->size->metrics.height / 2) >> 6);
- }
- if (font->fixed_width < 1) {
- font->fixed_width = 1;
- }
+ return true;
}
/** \} */
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index 4f25f99b65c..bcd9e1fb3a2 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -34,6 +34,7 @@
#include FT_GLYPH_H
#include FT_OUTLINE_H
#include FT_BITMAP_H
+#include FT_ADVANCES_H /* For FT_Get_Advance. */
#include "MEM_guardedalloc.h"
@@ -73,7 +74,7 @@ static FT_Fixed to_16dot16(double val)
/** \name Glyph Cache
* \{ */
-GlyphCacheBLF *blf_glyph_cache_find(FontBLF *font, float size, unsigned int dpi)
+static GlyphCacheBLF *blf_glyph_cache_find(FontBLF *font, float size, unsigned int dpi)
{
GlyphCacheBLF *gc = (GlyphCacheBLF *)font->cache.first;
while (gc) {
@@ -86,7 +87,7 @@ GlyphCacheBLF *blf_glyph_cache_find(FontBLF *font, float size, unsigned int dpi)
return NULL;
}
-GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font)
+static GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font)
{
GlyphCacheBLF *gc = (GlyphCacheBLF *)MEM_callocN(sizeof(GlyphCacheBLF), "blf_glyph_cache_new");
@@ -100,6 +101,22 @@ GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font)
memset(gc->glyph_ascii_table, 0, sizeof(gc->glyph_ascii_table));
memset(gc->bucket, 0, sizeof(gc->bucket));
+ /* Determine ideal fixed-width size for monospaced output. */
+ FT_UInt gindex = FT_Get_Char_Index(font->face, U'0');
+ if (gindex) {
+ FT_Fixed advance = 0;
+ FT_Get_Advance(font->face, gindex, FT_LOAD_NO_HINTING, &advance);
+ /* Use CSS 'ch unit' width, advance of zero character. */
+ gc->fixed_width = (int)(advance >> 16);
+ }
+ else {
+ /* Font does not contain "0" so use CSS fallback of 1/2 of em. */
+ gc->fixed_width = (int)((font->face->size->metrics.height / 2) >> 6);
+ }
+ if (gc->fixed_width < 1) {
+ gc->fixed_width = 1;
+ }
+
BLI_addhead(&font->cache, gc);
return gc;
}
@@ -122,20 +139,7 @@ void blf_glyph_cache_release(FontBLF *font)
BLI_spin_unlock(font->glyph_cache_mutex);
}
-void blf_glyph_cache_clear(FontBLF *font)
-{
- GlyphCacheBLF *gc;
-
- BLI_spin_lock(font->glyph_cache_mutex);
-
- while ((gc = BLI_pophead(&font->cache))) {
- blf_glyph_cache_free(gc);
- }
-
- BLI_spin_unlock(font->glyph_cache_mutex);
-}
-
-void blf_glyph_cache_free(GlyphCacheBLF *gc)
+static void blf_glyph_cache_free(GlyphCacheBLF *gc)
{
GlyphBLF *g;
for (uint i = 0; i < ARRAY_SIZE(gc->bucket); i++) {
@@ -152,6 +156,19 @@ void blf_glyph_cache_free(GlyphCacheBLF *gc)
MEM_freeN(gc);
}
+void blf_glyph_cache_clear(FontBLF *font)
+{
+ GlyphCacheBLF *gc;
+
+ BLI_spin_lock(font->glyph_cache_mutex);
+
+ while ((gc = BLI_pophead(&font->cache))) {
+ blf_glyph_cache_free(gc);
+ }
+
+ BLI_spin_unlock(font->glyph_cache_mutex);
+}
+
/**
* Try to find a glyph in cache.
*
diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h
index 4e36f522981..d0bb3385e2c 100644
--- a/source/blender/blenfont/intern/blf_internal.h
+++ b/source/blender/blenfont/intern/blf_internal.h
@@ -56,7 +56,11 @@ struct FontBLF *blf_font_new(const char *name, const char *filename);
struct FontBLF *blf_font_new_from_mem(const char *name, const unsigned char *mem, int mem_size);
void blf_font_attach_from_mem(struct FontBLF *font, const unsigned char *mem, int mem_size);
-void blf_font_size(struct FontBLF *font, float size, unsigned int dpi);
+/**
+ * Change font's output size. Returns true if successful in changing the size.
+ */
+bool blf_font_size(struct FontBLF *font, float size, unsigned int dpi);
+
void blf_font_draw(struct FontBLF *font,
const char *str,
size_t str_len,
@@ -65,10 +69,7 @@ void blf_font_draw__wrap(struct FontBLF *font,
const char *str,
size_t str_len,
struct ResultBLF *r_info);
-void blf_font_draw_ascii(struct FontBLF *font,
- const char *str,
- size_t str_len,
- struct ResultBLF *r_info);
+
/**
* Use fixed column width, but an utf8 character may occupy multiple columns.
*/
@@ -137,18 +138,9 @@ int blf_font_count_missing_chars(struct FontBLF *font,
void blf_font_free(struct FontBLF *font);
-/**
- * Find a glyph cache that matches a size, DPI & styles.
- */
-struct GlyphCacheBLF *blf_glyph_cache_find(struct FontBLF *font, float size, unsigned int dpi);
-/**
- * Create a new glyph cache for the current size, DPI & styles.
- */
-struct GlyphCacheBLF *blf_glyph_cache_new(struct FontBLF *font);
struct GlyphCacheBLF *blf_glyph_cache_acquire(struct FontBLF *font);
void blf_glyph_cache_release(struct FontBLF *font);
void blf_glyph_cache_clear(struct FontBLF *font);
-void blf_glyph_cache_free(struct GlyphCacheBLF *gc);
/**
* Create (or load from cache) a fully-rendered bitmap glyph.
diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h
index 46156edbb1f..c96febd71ae 100644
--- a/source/blender/blenfont/intern/blf_internal_types.h
+++ b/source/blender/blenfont/intern/blf_internal_types.h
@@ -73,6 +73,9 @@ typedef struct GlyphCacheBLF {
bool bold;
bool italic;
+ /* Column width when printing monospaced. */
+ int fixed_width;
+
/* and the glyphs. */
ListBase bucket[257];
@@ -207,9 +210,6 @@ typedef struct FontBLF {
/* font size. */
float size;
- /* Column width when printing monospaced. */
- int fixed_width;
-
/* max texture size. */
int tex_size_max;
diff --git a/source/blender/blenfont/intern/blf_thumbs.c b/source/blender/blenfont/intern/blf_thumbs.c
index 06bbd0cf521..f666976547e 100644
--- a/source/blender/blenfont/intern/blf_thumbs.c
+++ b/source/blender/blenfont/intern/blf_thumbs.c
@@ -61,7 +61,6 @@ void BLF_thumb_preview(const char *filename,
int font_shrink = 4;
FontBLF *font;
- GlyphCacheBLF *gc;
/* Create a new blender font obj and fill it with default values */
font = blf_font_new("thumb_font", filename);
@@ -90,10 +89,8 @@ void BLF_thumb_preview(const char *filename,
const size_t draw_str_i18n_len = strlen(draw_str_i18n);
int draw_str_i18n_nbr = 0;
- blf_font_size(font, (float)MAX2(font_size_min, font_size_curr), dpi);
- gc = blf_glyph_cache_find(font, font->size, font->dpi);
- /* There will be no matching glyph cache if blf_font_size() failed to set font size. */
- if (!gc) {
+ CLAMP_MIN(font_size_curr, font_size_min);
+ if (!blf_font_size(font, (float)font_size_curr, dpi)) {
break;
}
diff --git a/source/blender/blenkernel/BKE_attribute_math.hh b/source/blender/blenkernel/BKE_attribute_math.hh
index 90f349125c9..bf773cd6d75 100644
--- a/source/blender/blenkernel/BKE_attribute_math.hh
+++ b/source/blender/blenkernel/BKE_attribute_math.hh
@@ -50,6 +50,9 @@ inline void convert_to_static_type(const CustomDataType data_type, const Func &f
case CD_PROP_BOOL:
func(bool());
break;
+ case CD_PROP_INT8:
+ func(int8_t());
+ break;
case CD_PROP_COLOR:
func(ColorGeometry4f());
break;
@@ -77,6 +80,9 @@ inline void convert_to_static_type(const fn::CPPType &cpp_type, const Func &func
else if (cpp_type.is<bool>()) {
func(bool());
}
+ else if (cpp_type.is<int8_t>()) {
+ func(int8_t());
+ }
else if (cpp_type.is<ColorGeometry4f>()) {
func(ColorGeometry4f());
}
@@ -93,6 +99,12 @@ inline void convert_to_static_type(const fn::CPPType &cpp_type, const Func &func
template<typename T> T mix3(const float3 &weights, const T &v0, const T &v1, const T &v2);
+template<>
+inline int8_t mix3(const float3 &weights, const int8_t &v0, const int8_t &v1, const int8_t &v2)
+{
+ return static_cast<int8_t>(weights.x * v0 + weights.y * v1 + weights.z * v2);
+}
+
template<> inline bool mix3(const float3 &weights, const bool &v0, const bool &v1, const bool &v2)
{
return (weights.x * v0 + weights.y * v1 + weights.z * v2) >= 0.5f;
@@ -147,6 +159,11 @@ template<> inline bool mix2(const float factor, const bool &a, const bool &b)
return ((1.0f - factor) * a + factor * b) >= 0.5f;
}
+template<> inline int8_t mix2(const float factor, const int8_t &a, const int8_t &b)
+{
+ return static_cast<int8_t>((1.0f - factor) * a + factor * b);
+}
+
template<> inline int mix2(const float factor, const int &a, const int &b)
{
return static_cast<int>((1.0f - factor) * a + factor * b);
@@ -364,6 +381,15 @@ template<> struct DefaultMixerStruct<bool> {
using type = SimpleMixerWithAccumulationType<bool, float, float_to_bool>;
};
+template<> struct DefaultMixerStruct<int8_t> {
+ static int8_t float_to_int8_t(const float &value)
+ {
+ return static_cast<int8_t>(value);
+ }
+ /* Store interpolated 8 bit integers in a float temporarily to increase accuracy. */
+ using type = SimpleMixerWithAccumulationType<int8_t, float, float_to_int8_t>;
+};
+
template<typename T> struct DefaultPropatationMixerStruct {
/* Use void by default. This can be checked for in `if constexpr` statements. */
using type = typename DefaultMixerStruct<T>::type;
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index 645d049fe71..fe656166ada 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 1
+#define BLENDER_FILE_SUBVERSION 2
/* 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/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc
index aa810afd3ef..2e779d6fad7 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.cc
+++ b/source/blender/blenkernel/intern/DerivedMesh.cc
@@ -1585,13 +1585,6 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
BKE_id_free(nullptr, mesh_orco);
}
- /* Ensure normals calculation below is correct (normal settings have transferred properly).
- * However, nodes modifiers might create meshes from scratch or transfer meshes from other
- * objects with different settings, and in general it doesn't make sense to guarantee that
- * the settings are the same as the original mesh. If necessary, this could become a modifier
- * type flag. */
- BLI_assert(mesh_input->smoothresh == mesh_cage->smoothresh);
-
/* Compute normals. */
editbmesh_calc_modifier_final_normals(mesh_final, &final_datamask);
if (mesh_cage && (mesh_cage != mesh_final)) {
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index cc43a3e26a8..68ab11a013b 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -83,6 +83,8 @@ const blender::fn::CPPType *custom_data_type_to_cpp_type(const CustomDataType ty
return &CPPType::get<ColorGeometry4f>();
case CD_PROP_BOOL:
return &CPPType::get<bool>();
+ case CD_PROP_INT8:
+ return &CPPType::get<int8_t>();
default:
return nullptr;
}
@@ -109,6 +111,9 @@ CustomDataType cpp_type_to_custom_data_type(const blender::fn::CPPType &type)
if (type.is<bool>()) {
return CD_PROP_BOOL;
}
+ if (type.is<int8_t>()) {
+ return CD_PROP_INT8;
+ }
return static_cast<CustomDataType>(-1);
}
@@ -117,16 +122,18 @@ static int attribute_data_type_complexity(const CustomDataType data_type)
switch (data_type) {
case CD_PROP_BOOL:
return 0;
- case CD_PROP_INT32:
+ case CD_PROP_INT8:
return 1;
- case CD_PROP_FLOAT:
+ case CD_PROP_INT32:
return 2;
- case CD_PROP_FLOAT2:
+ case CD_PROP_FLOAT:
return 3;
- case CD_PROP_FLOAT3:
+ case CD_PROP_FLOAT2:
return 4;
- case CD_PROP_COLOR:
+ case CD_PROP_FLOAT3:
return 5;
+ case CD_PROP_COLOR:
+ return 6;
#if 0 /* These attribute types are not supported yet. */
case CD_MLOOPCOL:
return 3;
diff --git a/source/blender/blenkernel/intern/attribute_access_intern.hh b/source/blender/blenkernel/intern/attribute_access_intern.hh
index 2cd128081eb..5341266e182 100644
--- a/source/blender/blenkernel/intern/attribute_access_intern.hh
+++ b/source/blender/blenkernel/intern/attribute_access_intern.hh
@@ -140,7 +140,8 @@ class CustomDataAttributeProvider final : public DynamicAttributesProvider {
private:
static constexpr uint64_t supported_types_mask = CD_MASK_PROP_FLOAT | CD_MASK_PROP_FLOAT2 |
CD_MASK_PROP_FLOAT3 | CD_MASK_PROP_INT32 |
- CD_MASK_PROP_COLOR | CD_MASK_PROP_BOOL;
+ CD_MASK_PROP_COLOR | CD_MASK_PROP_BOOL |
+ CD_MASK_PROP_INT8;
const AttributeDomain domain_;
const CustomDataAccessInfo custom_data_access_;
diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc
index db30e223185..36d511422aa 100644
--- a/source/blender/blenkernel/intern/customdata.cc
+++ b/source/blender/blenkernel/intern/customdata.cc
@@ -1793,8 +1793,8 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(float[3]), "vec3f", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
/* 44: CD_RADIUS */
{sizeof(float), "MFloatProperty", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
- /* 45: CD_HAIRCURVE */ /* UNUSED */
- {-1, "", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
+ /* 45: CD_PROP_INT8 */
+ {sizeof(int8_t), "MInt8Property", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
/* 46: CD_HAIRMAPPING */ /* UNUSED */
{-1, "", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
/* 47: CD_PROP_COLOR */
@@ -1914,7 +1914,7 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
"CDCustomLoopNormal",
"CDSculptFaceGroups",
/* 43-46 */ "CDHairPoint",
- "CDHairCurve",
+ "CDPropInt8",
"CDHairMapping",
"CDPoint",
"CDPropCol",
diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc
index 73fe279552d..c1b1f62a881 100644
--- a/source/blender/blenkernel/intern/mesh.cc
+++ b/source/blender/blenkernel/intern/mesh.cc
@@ -685,6 +685,17 @@ static int customdata_compare(
}
break;
}
+ case CD_PROP_INT8: {
+ const int8_t *l1_data = (int8_t *)l1->data;
+ const int8_t *l2_data = (int8_t *)l2->data;
+
+ for (int i = 0; i < total_length; i++) {
+ if (l1_data[i] != l2_data[i]) {
+ return MESHCMP_ATTRIBUTE_VALUE_MISMATCH;
+ }
+ }
+ break;
+ }
case CD_PROP_BOOL: {
const bool *l1_data = (bool *)l1->data;
const bool *l2_data = (bool *)l2->data;
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 0677b1adb6d..a1c10a733ce 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -648,7 +648,6 @@ static void ntree_blend_write(BlendWriter *writer, ID *id, const void *id_addres
bNodeTree *ntree = (bNodeTree *)id;
/* Clean up, important in undo case to reduce false detection of changed datablocks. */
- ntree->init = 0; /* to set callbacks and force setting types */
ntree->is_updating = false;
ntree->typeinfo = nullptr;
ntree->interface_type = nullptr;
@@ -677,7 +676,6 @@ static void direct_link_node_socket(BlendDataReader *reader, bNodeSocket *sock)
void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
{
/* NOTE: writing and reading goes in sync, for speed. */
- ntree->init = 0; /* to set callbacks and force setting types */
ntree->is_updating = false;
ntree->typeinfo = nullptr;
ntree->interface_type = nullptr;
@@ -1145,8 +1143,6 @@ static void ntree_set_typeinfo(bNodeTree *ntree, bNodeTreeType *typeinfo)
}
else {
ntree->typeinfo = &NodeTreeTypeUndefined;
-
- ntree->init &= ~NTREE_TYPE_INIT;
}
/* Deprecated integer type. */
@@ -1177,8 +1173,6 @@ static void node_set_typeinfo(const struct bContext *C,
}
else {
node->typeinfo = &NodeTypeUndefined;
-
- ntree->init &= ~NTREE_TYPE_INIT;
}
}
@@ -1199,8 +1193,6 @@ static void node_socket_set_typeinfo(bNodeTree *ntree,
}
else {
sock->typeinfo = &NodeSocketTypeUndefined;
-
- ntree->init &= ~NTREE_TYPE_INIT;
}
BKE_ntree_update_tag_socket_type(ntree, sock);
}
@@ -1218,8 +1210,6 @@ static void update_typeinfo(Main *bmain,
}
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
- ntree->init |= NTREE_TYPE_INIT;
-
if (treetype && STREQ(ntree->idname, treetype->idname)) {
ntree_set_typeinfo(ntree, unregister ? nullptr : treetype);
}
@@ -1260,8 +1250,6 @@ static void update_typeinfo(Main *bmain,
void ntreeSetTypes(const struct bContext *C, bNodeTree *ntree)
{
- ntree->init |= NTREE_TYPE_INIT;
-
ntree_set_typeinfo(ntree, ntreeTypeFind(ntree->idname));
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
@@ -2674,11 +2662,6 @@ bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname)
ntree->id.flag |= LIB_EMBEDDED_DATA;
}
- /* Types are fully initialized at this point,
- * if an undefined node is added later this will be reset.
- */
- ntree->init |= NTREE_TYPE_INIT;
-
BLI_strncpy(ntree->idname, idname, sizeof(ntree->idname));
ntree_set_typeinfo(ntree, ntreeTypeFind(idname));
diff --git a/source/blender/blenkernel/intern/type_conversions.cc b/source/blender/blenkernel/intern/type_conversions.cc
index cb05337ef2a..b2011d2baf7 100644
--- a/source/blender/blenkernel/intern/type_conversions.cc
+++ b/source/blender/blenkernel/intern/type_conversions.cc
@@ -62,6 +62,11 @@ static bool float_to_bool(const float &a)
{
return a > 0.0f;
}
+static int8_t float_to_int8(const float &a)
+{
+ return std::clamp(
+ a, float(std::numeric_limits<int8_t>::min()), float(std::numeric_limits<int8_t>::max()));
+}
static ColorGeometry4f float_to_color(const float &a)
{
return ColorGeometry4f(a, a, a, 1.0f);
@@ -83,6 +88,10 @@ static bool float2_to_bool(const float2 &a)
{
return !is_zero_v2(a);
}
+static int8_t float2_to_int8(const float2 &a)
+{
+ return float_to_int8((a.x + a.y) / 2.0f);
+}
static ColorGeometry4f float2_to_color(const float2 &a)
{
return ColorGeometry4f(a.x, a.y, 0.0f, 1.0f);
@@ -92,6 +101,10 @@ static bool float3_to_bool(const float3 &a)
{
return !is_zero_v3(a);
}
+static int8_t float3_to_int8(const float3 &a)
+{
+ return float_to_int8((a.x + a.y + a.z) / 3.0f);
+}
static float float3_to_float(const float3 &a)
{
return (a.x + a.y + a.z) / 3.0f;
@@ -113,6 +126,11 @@ static bool int_to_bool(const int32_t &a)
{
return a > 0;
}
+static int8_t int_to_int8(const int32_t &a)
+{
+ return std::clamp(
+ a, int(std::numeric_limits<int8_t>::min()), int(std::numeric_limits<int8_t>::max()));
+}
static float int_to_float(const int32_t &a)
{
return (float)a;
@@ -130,10 +148,39 @@ static ColorGeometry4f int_to_color(const int32_t &a)
return ColorGeometry4f((float)a, (float)a, (float)a, 1.0f);
}
+static bool int8_to_bool(const int8_t &a)
+{
+ return a > 0;
+}
+static int int8_to_int(const int8_t &a)
+{
+ return static_cast<int>(a);
+}
+static float int8_to_float(const int8_t &a)
+{
+ return (float)a;
+}
+static float2 int8_to_float2(const int8_t &a)
+{
+ return float2((float)a);
+}
+static float3 int8_to_float3(const int8_t &a)
+{
+ return float3((float)a);
+}
+static ColorGeometry4f int8_to_color(const int8_t &a)
+{
+ return ColorGeometry4f((float)a, (float)a, (float)a, 1.0f);
+}
+
static float bool_to_float(const bool &a)
{
return (bool)a;
}
+static int8_t bool_to_int8(const bool &a)
+{
+ return static_cast<int8_t>(a);
+}
static int32_t bool_to_int(const bool &a)
{
return (int32_t)a;
@@ -163,6 +210,10 @@ static int32_t color_to_int(const ColorGeometry4f &a)
{
return (int)rgb_to_grayscale(a);
}
+static int8_t color_to_int8(const ColorGeometry4f &a)
+{
+ return int_to_int8(color_to_int(a));
+}
static float2 color_to_float2(const ColorGeometry4f &a)
{
return float2(a.r, a.g);
@@ -180,33 +231,46 @@ static DataTypeConversions create_implicit_conversions()
add_implicit_conversion<float, float3, float_to_float3>(conversions);
add_implicit_conversion<float, int32_t, float_to_int>(conversions);
add_implicit_conversion<float, bool, float_to_bool>(conversions);
+ add_implicit_conversion<float, int8_t, float_to_int8>(conversions);
add_implicit_conversion<float, ColorGeometry4f, float_to_color>(conversions);
add_implicit_conversion<float2, float3, float2_to_float3>(conversions);
add_implicit_conversion<float2, float, float2_to_float>(conversions);
add_implicit_conversion<float2, int32_t, float2_to_int>(conversions);
add_implicit_conversion<float2, bool, float2_to_bool>(conversions);
+ add_implicit_conversion<float2, int8_t, float2_to_int8>(conversions);
add_implicit_conversion<float2, ColorGeometry4f, float2_to_color>(conversions);
add_implicit_conversion<float3, bool, float3_to_bool>(conversions);
+ add_implicit_conversion<float3, int8_t, float3_to_int8>(conversions);
add_implicit_conversion<float3, float, float3_to_float>(conversions);
add_implicit_conversion<float3, int32_t, float3_to_int>(conversions);
add_implicit_conversion<float3, float2, float3_to_float2>(conversions);
add_implicit_conversion<float3, ColorGeometry4f, float3_to_color>(conversions);
add_implicit_conversion<int32_t, bool, int_to_bool>(conversions);
+ add_implicit_conversion<int32_t, int8_t, int_to_int8>(conversions);
add_implicit_conversion<int32_t, float, int_to_float>(conversions);
add_implicit_conversion<int32_t, float2, int_to_float2>(conversions);
add_implicit_conversion<int32_t, float3, int_to_float3>(conversions);
add_implicit_conversion<int32_t, ColorGeometry4f, int_to_color>(conversions);
+ add_implicit_conversion<int8_t, bool, int8_to_bool>(conversions);
+ add_implicit_conversion<int8_t, int32_t, int8_to_int>(conversions);
+ add_implicit_conversion<int8_t, float, int8_to_float>(conversions);
+ add_implicit_conversion<int8_t, float2, int8_to_float2>(conversions);
+ add_implicit_conversion<int8_t, float3, int8_to_float3>(conversions);
+ add_implicit_conversion<int8_t, ColorGeometry4f, int8_to_color>(conversions);
+
add_implicit_conversion<bool, float, bool_to_float>(conversions);
+ add_implicit_conversion<bool, int8_t, bool_to_int8>(conversions);
add_implicit_conversion<bool, int32_t, bool_to_int>(conversions);
add_implicit_conversion<bool, float2, bool_to_float2>(conversions);
add_implicit_conversion<bool, float3, bool_to_float3>(conversions);
add_implicit_conversion<bool, ColorGeometry4f, bool_to_color>(conversions);
add_implicit_conversion<ColorGeometry4f, bool, color_to_bool>(conversions);
+ add_implicit_conversion<ColorGeometry4f, int8_t, color_to_int8>(conversions);
add_implicit_conversion<ColorGeometry4f, float, color_to_float>(conversions);
add_implicit_conversion<ColorGeometry4f, int32_t, color_to_int>(conversions);
add_implicit_conversion<ColorGeometry4f, float2, color_to_float2>(conversions);
diff --git a/source/blender/blenlib/BLI_enumerable_thread_specific.hh b/source/blender/blenlib/BLI_enumerable_thread_specific.hh
index b5981028893..ce7df1ff4b9 100644
--- a/source/blender/blenlib/BLI_enumerable_thread_specific.hh
+++ b/source/blender/blenlib/BLI_enumerable_thread_specific.hh
@@ -28,10 +28,12 @@
namespace blender::threading {
+#ifndef WITH_TBB
namespace enumerable_thread_specific_utils {
inline std::atomic<int> next_id = 0;
inline thread_local int thread_id = next_id.fetch_add(1, std::memory_order_relaxed);
} // namespace enumerable_thread_specific_utils
+#endif
/**
* This is mainly a wrapper for `tbb::enumerable_thread_specific`. The wrapper is needed because we
diff --git a/source/blender/blenlib/BLI_string_ref.hh b/source/blender/blenlib/BLI_string_ref.hh
index f72106aa961..32a03213dc1 100644
--- a/source/blender/blenlib/BLI_string_ref.hh
+++ b/source/blender/blenlib/BLI_string_ref.hh
@@ -373,8 +373,7 @@ constexpr int64_t StringRefBase::find_last_of(StringRef chars, int64_t pos) cons
constexpr int64_t StringRefBase::find_last_of(char c, int64_t pos) const
{
BLI_assert(pos >= 0);
- return index_or_npos_to_int64(
- std::string_view(*this).find_last_of(c, static_cast<size_t>(pos)));
+ return index_or_npos_to_int64(std::string_view(*this).find_last_of(c, static_cast<size_t>(pos)));
}
constexpr int64_t StringRefBase::find_first_not_of(StringRef chars, int64_t pos) const
diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c
index 90730439c51..001dffdca10 100644
--- a/source/blender/blenloader/intern/versioning_300.c
+++ b/source/blender/blenloader/intern/versioning_300.c
@@ -1107,6 +1107,15 @@ static bool seq_transform_origin_set(Sequence *seq, void *UNUSED(user_data))
return true;
}
+static bool seq_transform_filter_set(Sequence *seq, void *UNUSED(user_data))
+{
+ StripTransform *transform = seq->strip->transform;
+ if (seq->strip->transform != NULL) {
+ transform->filter = SEQ_TRANSFORM_FILTER_BILINEAR;
+ }
+ return true;
+}
+
static void do_version_subsurface_methods(bNode *node)
{
if (node->type == SH_NODE_SUBSURFACE_SCATTERING) {
@@ -2549,6 +2558,14 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
+ if (!MAIN_VERSION_ATLEAST(bmain, 302, 2)) {
+ LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
+ if (scene->ed != NULL) {
+ SEQ_for_each_callback(&scene->ed->seqbase, seq_transform_filter_set, NULL);
+ }
+ }
+ }
+
/**
* Versioning code until next subversion bump goes here.
*
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 2f471bf0b81..b429399f310 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -451,6 +451,16 @@ static bool nearly_parallel_normalized(const float d1[3], const float d2[3])
return compare_ff(fabsf(direction_dot), 1.0f, BEVEL_EPSILON_ANG_DOT);
}
+/**
+ * calculate the determinant of a matrix formed by three vectors
+ * \return dot(a, cross(b, c)) = determinant(a, b, c)
+ */
+static float determinant_v3v3v3(const float a[3], const float b[3], const float c[3])
+{
+ return a[0] * b[1] * c[2] + a[1] * b[2] * c[0] + a[2] * b[0] * c[1] - a[0] * b[2] * c[1] -
+ a[1] * b[0] * c[2] - a[2] * b[1] * c[0];
+}
+
/* Make a new BoundVert of the given kind, inserting it at the end of the circular linked
* list with entry point bv->boundstart, and return it. */
static BoundVert *add_new_bound_vert(MemArena *mem_arena, VMesh *vm, const float co[3])
@@ -4118,44 +4128,114 @@ static VMesh *cubic_subdiv(BevelParams *bp, VMesh *vm_in)
VMesh *vm_out = new_adj_vmesh(bp->mem_arena, n_boundary, ns_out, vm_in->boundstart);
/* First we adjust the boundary vertices of the input mesh, storing in output mesh. */
+ BoundVert *bndv = vm_in->boundstart;
for (int i = 0; i < n_boundary; i++) {
+ float co1[3], co2[3], acc[3];
+ EdgeHalf *e = bndv->elast;
+ /* Generate tangents. This is hacked together and would ideally be done elsewhere and then only
+ * used here. */
+ float tangent[3], tangent2[3], normal[3];
+ bool convex = true;
+ bool orthogonal = false;
+ float stretch = 0.0f;
+ if (e) {
+ /* Projection direction is direction of the edge. */
+ sub_v3_v3v3(tangent, e->e->v1->co, e->e->v2->co);
+ if (e->is_rev) {
+ negate_v3(tangent);
+ }
+ normalize_v3(tangent);
+ if (bndv->is_arc_start || bndv->is_patch_start) {
+ BMFace *face = e->fnext;
+ if (face) {
+ copy_v3_v3(normal, face->no);
+ }
+ else {
+ zero_v3(normal);
+ }
+ madd_v3_v3v3fl(co2, bndv->profile.middle, normal, 0.1f);
+ }
+ if (bndv->is_arc_start || bp->affect_type == BEVEL_AFFECT_VERTICES) {
+ EdgeHalf *e1 = bndv->next->elast;
+ BLI_assert(e1);
+ sub_v3_v3v3(tangent2, e1->e->v1->co, e1->e->v2->co);
+ if (e1->is_rev) {
+ negate_v3(tangent2);
+ }
+ normalize_v3(tangent2);
+
+ convex = determinant_v3v3v3(tangent2, tangent, normal) < 0;
+
+ add_v3_v3(tangent2, tangent);
+ normalize_v3(tangent2);
+ copy_v3_v3(tangent, tangent2);
+ }
+ /* Calculate a factor which determines how much the interpolated mesh is
+ * going to be stretched out into the direction of the tangent.
+ * It is currently using the difference along the tangent of the
+ * central point on the profile and the current center vertex position. */
+ get_profile_point(bp, &bndv->profile, ns_in2, ns_in, co);
+ stretch = dot_v3v3(tangent, mesh_vert(vm_in, i, ns_in2, ns_in2)->co) - dot_v3v3(tangent, co);
+ stretch = fabsf(stretch);
+ /* Scale the tangent by stretch. The divide by ns_in2 comes from the Levin Paper. */
+ mul_v3_fl(tangent, stretch / ns_in2);
+ orthogonal = bndv->is_patch_start;
+ }
+ else if (bndv->prev->is_patch_start) {
+ /* If this is the second edge of a patch and therefore #e is NULL,
+ * then e->fprev has to be used/not NULL. */
+ BLI_assert(bndv->prev->elast);
+ BMFace *face = bndv->prev->elast->fnext;
+ if (face) {
+ copy_v3_v3(normal, face->no);
+ }
+ else {
+ zero_v3(normal);
+ }
+ orthogonal = true;
+ }
+ else {
+ /** Should only come here from make_cube_corner_adj_vmesh. */
+ sub_v3_v3v3(co1, mesh_vert(vm_in, i, 0, 0)->co, mesh_vert(vm_in, i, 0, 1)->co);
+ sub_v3_v3v3(co2, mesh_vert(vm_in, i, 0, 1)->co, mesh_vert(vm_in, i, 0, 2)->co);
+ cross_v3_v3v3(tangent, co1, co2);
+ /** The following constant is chosen to best match the old results. */
+ normalize_v3_length(tangent, 1.5f / ns_out);
+ }
+ /** Copy corner vertex. */
copy_v3_v3(mesh_vert(vm_out, i, 0, 0)->co, mesh_vert(vm_in, i, 0, 0)->co);
+ /** Copy the rest of the boundary vertices. */
for (int k = 1; k < ns_in; k++) {
copy_v3_v3(co, mesh_vert(vm_in, i, 0, k)->co);
- /* Smooth boundary rule. Custom profiles shouldn't be smoothed. */
- if (bp->profile_type != BEVEL_PROFILE_CUSTOM) {
- float co1[3], co2[3], acc[3];
- copy_v3_v3(co1, mesh_vert(vm_in, i, 0, k - 1)->co);
- copy_v3_v3(co2, mesh_vert(vm_in, i, 0, k + 1)->co);
-
- add_v3_v3v3(acc, co1, co2);
- madd_v3_v3fl(acc, co, -2.0f);
- madd_v3_v3fl(co, acc, -1.0f / 6.0f);
- }
+ copy_v3_v3(co1, mesh_vert(vm_in, i, 0, k - 1)->co);
+ copy_v3_v3(co2, mesh_vert(vm_in, i, 0, k + 1)->co);
+
+ add_v3_v3v3(acc, co1, co2);
+ if (bndv->is_arc_start) {
+ sub_v3_v3(co1, co);
+ sub_v3_v3(co2, co);
+ normalize_v3(co1);
+ normalize_v3(co2);
+ add_v3_v3v3(tangent, co1, co2);
+ /* This is an empirical formula to make the result look good. */
+ normalize_v3(tangent);
+ float dot = convex ? fminf(0, dot_v3v3(tangent2, tangent)) : 1.0f;
+ mul_v3_fl(tangent, stretch / ns_in * dot);
+ }
+ else if (orthogonal) {
+ sub_v3_v3(co1, co);
+ cross_v3_v3v3(tangent, normal, co1);
+ /* This is an empirical formula to make the result look good. */
+ normalize_v3_length(tangent, -bp->offset * 0.7071f / ns_in);
+ }
+ mul_v3_fl(co, 2.0f);
+ madd_v3_v3fl(co, acc, -0.25f);
+ madd_v3_v3fl(co, mesh_vert(vm_in, i, 1, k)->co, -0.5f);
+ add_v3_v3(co, tangent);
copy_v3_v3(mesh_vert_canon(vm_out, i, 0, 2 * k)->co, co);
}
- }
- /* Now adjust odd boundary vertices in output mesh, based on even ones. */
- BoundVert *bndv = vm_out->boundstart;
- for (int i = 0; i < n_boundary; i++) {
- for (int k = 1; k < ns_out; k += 2) {
- get_profile_point(bp, &bndv->profile, k, ns_out, co);
-
- /* Smooth if using a non-custom profile. */
- if (bp->profile_type != BEVEL_PROFILE_CUSTOM) {
- float co1[3], co2[3], acc[3];
- copy_v3_v3(co1, mesh_vert_canon(vm_out, i, 0, k - 1)->co);
- copy_v3_v3(co2, mesh_vert_canon(vm_out, i, 0, k + 1)->co);
-
- add_v3_v3v3(acc, co1, co2);
- madd_v3_v3fl(acc, co, -2.0f);
- madd_v3_v3fl(co, acc, -1.0f / 6.0f);
- }
-
- copy_v3_v3(mesh_vert_canon(vm_out, i, 0, k)->co, co);
- }
bndv = bndv->next;
}
vmesh_copy_equiv_verts(vm_out);
@@ -4163,7 +4243,7 @@ static VMesh *cubic_subdiv(BevelParams *bp, VMesh *vm_in)
/* Copy adjusted verts back into vm_in. */
for (int i = 0; i < n_boundary; i++) {
for (int k = 0; k < ns_in; k++) {
- copy_v3_v3(mesh_vert(vm_in, i, 0, k)->co, mesh_vert(vm_out, i, 0, 2 * k)->co);
+ copy_v3_v3(mesh_vert_canon(vm_in, i, 0, k)->co, mesh_vert_canon(vm_out, i, 0, 2 * k)->co);
}
}
@@ -4248,7 +4328,7 @@ static VMesh *cubic_subdiv(BevelParams *bp, VMesh *vm_in)
vmesh_copy_equiv_verts(vm_out);
/* The center vertex is special. */
- gamma = sabin_gamma(n_boundary);
+ gamma = sabin_gamma(n_boundary) * 0.5f;
beta = -gamma;
/* Accumulate edge verts in co1, face verts in co2. */
float co1[3], co2[3];
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index d346fcf0f94..97dae46c75f 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -1992,7 +1992,7 @@ void DepsgraphRelationBuilder::build_particle_settings(ParticleSettings *part)
"Particle Texture -> Particle Reset",
RELATION_FLAG_FLUSH_USER_EDIT_ONLY);
add_relation(texture_key, particle_settings_eval_key, "Particle Texture -> Particle Eval");
- /* TODO(sergey): Consider moving texture space handling to an own
+ /* TODO(sergey): Consider moving texture space handling to its own
* function. */
if (mtex->texco == TEXCO_OBJECT && mtex->object != nullptr) {
ComponentKey object_key(&mtex->object->id, NodeType::TRANSFORM);
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
index d6f6e32e798..95b3044b40c 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
@@ -647,8 +647,8 @@ void set_particle_system_modifiers_loaded(Object *object_cow)
void reset_particle_system_edit_eval(const Depsgraph *depsgraph, Object *object_cow)
{
- /* Inactive (and render) dependency graphs are living in own little bubble, should not care about
- * edit mode at all. */
+ /* Inactive (and render) dependency graphs are living in their own little bubble, should not care
+ * about edit mode at all. */
if (!DEG_is_active(reinterpret_cast<const ::Depsgraph *>(depsgraph))) {
return;
}
diff --git a/source/blender/draw/engines/image/image_drawing_mode.hh b/source/blender/draw/engines/image/image_drawing_mode.hh
index cc85f1e098f..52d57ea2ba5 100644
--- a/source/blender/draw/engines/image/image_drawing_mode.hh
+++ b/source/blender/draw/engines/image/image_drawing_mode.hh
@@ -393,7 +393,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
*
* Returns true when a float buffer was created. Somehow the VSE cache increases the ref
* counter, but might use a different mechanism for destructing the image, that doesn't free the
- * rect_float as the refcounter isn't 0. To work around this we destruct any created local
+ * rect_float as the reference-counter isn't 0. To work around this we destruct any created local
* buffers ourself.
*/
bool ensure_float_buffer(ImBuf &image_buffer) const
diff --git a/source/blender/draw/engines/overlay/overlay_armature.c b/source/blender/draw/engines/overlay/overlay_armature.c
index 650dfa85c5c..ccf8f9e0c36 100644
--- a/source/blender/draw/engines/overlay/overlay_armature.c
+++ b/source/blender/draw/engines/overlay/overlay_armature.c
@@ -191,20 +191,17 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata)
sh = OVERLAY_shader_armature_sphere(false);
grp = DRW_shgroup_create(sh, armature_ps);
- DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
DRW_shgroup_uniform_float_copy(grp, "alpha", 1.0f);
cb->solid.point_fill = BUF_INSTANCE(grp, format, DRW_cache_bone_point_get());
grp = DRW_shgroup_create(sh, armature_ps);
DRW_shgroup_state_disable(grp, DRW_STATE_WRITE_DEPTH);
DRW_shgroup_state_enable(grp, DRW_STATE_BLEND_ALPHA);
- DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
DRW_shgroup_uniform_float_copy(grp, "alpha", wire_alpha * 0.4f);
cb->transp.point_fill = BUF_INSTANCE(grp, format, DRW_cache_bone_point_get());
sh = OVERLAY_shader_armature_shape(false);
grp = DRW_shgroup_create(sh, armature_ps);
- DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
DRW_shgroup_uniform_float_copy(grp, "alpha", 1.0f);
cb->solid.custom_fill = grp;
cb->solid.box_fill = BUF_INSTANCE(grp, format, DRW_cache_bone_box_get());
@@ -213,7 +210,6 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata)
grp = DRW_shgroup_create(sh, armature_ps);
DRW_shgroup_state_disable(grp, DRW_STATE_WRITE_DEPTH);
DRW_shgroup_state_enable(grp, DRW_STATE_BLEND_ALPHA);
- DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
DRW_shgroup_uniform_float_copy(grp, "alpha", wire_alpha * 0.6f);
cb->transp.custom_fill = grp;
cb->transp.box_fill = BUF_INSTANCE(grp, format, DRW_cache_bone_box_get());
@@ -335,7 +331,6 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata)
sh = OVERLAY_shader_armature_envelope(false);
grp = DRW_shgroup_create(sh, armature_ps);
DRW_shgroup_state_enable(grp, DRW_STATE_CULL_BACK);
- DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
DRW_shgroup_uniform_bool_copy(grp, "isDistance", false);
DRW_shgroup_uniform_float_copy(grp, "alpha", 1.0f);
cb->solid.envelope_fill = BUF_INSTANCE(grp, format, DRW_cache_bone_envelope_solid_get());
@@ -371,7 +366,6 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata)
sh = OVERLAY_shader_armature_envelope(false);
grp = DRW_shgroup_create(sh, armature_transp_ps);
- DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
DRW_shgroup_uniform_float_copy(grp, "alpha", 1.0f);
DRW_shgroup_uniform_bool_copy(grp, "isDistance", true);
DRW_shgroup_state_enable(grp, DRW_STATE_CULL_FRONT);
diff --git a/source/blender/draw/engines/overlay/overlay_fade.c b/source/blender/draw/engines/overlay/overlay_fade.c
index 0971021f1c0..557a8976ff7 100644
--- a/source/blender/draw/engines/overlay/overlay_fade.c
+++ b/source/blender/draw/engines/overlay/overlay_fade.c
@@ -43,7 +43,6 @@ void OVERLAY_fade_cache_init(OVERLAY_Data *vedata)
GPUShader *sh = OVERLAY_shader_uniform_color();
pd->fade_grp[i] = DRW_shgroup_create(sh, psl->fade_ps[i]);
- DRW_shgroup_uniform_block(pd->fade_grp[i], "globalsBlock", G_draw.block_ubo);
const DRWContextState *draw_ctx = DRW_context_state_get();
float color[4];
diff --git a/source/blender/draw/engines/overlay/overlay_volume.c b/source/blender/draw/engines/overlay/overlay_volume.c
index ad0ccf1c7c4..b13351984a3 100644
--- a/source/blender/draw/engines/overlay/overlay_volume.c
+++ b/source/blender/draw/engines/overlay/overlay_volume.c
@@ -37,7 +37,6 @@ void OVERLAY_volume_cache_init(OVERLAY_Data *vedata)
GPUShader *sh = OVERLAY_shader_depth_only();
DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->volume_ps);
pd->volume_selection_surface_grp = grp;
- DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
}
else {
psl->volume_ps = NULL;
diff --git a/source/blender/draw/engines/overlay/shaders/edit_uv_edges_frag.glsl b/source/blender/draw/engines/overlay/shaders/edit_uv_edges_frag.glsl
index f7792dc0371..8f90c1acbbb 100644
--- a/source/blender/draw/engines/overlay/shaders/edit_uv_edges_frag.glsl
+++ b/source/blender/draw/engines/overlay/shaders/edit_uv_edges_frag.glsl
@@ -40,7 +40,7 @@ void main()
}
else if (lineStyle == OVERLAY_UV_LINE_STYLE_DASH) {
if (fract(line_distance / dashLength) < 0.5) {
- inner_color = mix(vec4(1.0), colorEdgeSelect, selectionFac_f);
+ inner_color = mix(vec4(vec3(0.35), 1.0), colorEdgeSelect, selectionFac_f);
}
}
else if (lineStyle == OVERLAY_UV_LINE_STYLE_BLACK) {
diff --git a/source/blender/draw/engines/workbench/shaders/infos/workbench_composite_info.hh b/source/blender/draw/engines/workbench/shaders/infos/workbench_composite_info.hh
index f577ae197b4..e93f241ad3c 100644
--- a/source/blender/draw/engines/workbench/shaders/infos/workbench_composite_info.hh
+++ b/source/blender/draw/engines/workbench/shaders/infos/workbench_composite_info.hh
@@ -13,7 +13,7 @@ GPU_SHADER_CREATE_INFO(workbench_composite)
.fragment_out(0, Type::VEC4, "fragColor")
.typedef_source("workbench_shader_shared.h")
.fragment_source("workbench_composite_frag.glsl")
- .additional_info("draw_fullscreen");
+ .additional_info("draw_fullscreen", "draw_view");
/** \} */
diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c
index 0a0c20b0d6a..0dfc3c4b119 100644
--- a/source/blender/draw/engines/workbench/workbench_engine.c
+++ b/source/blender/draw/engines/workbench/workbench_engine.c
@@ -28,6 +28,7 @@
#include "BLI_alloca.h"
+#include "BKE_editmesh.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_paint.h"
@@ -239,6 +240,26 @@ static void workbench_cache_hair_populate(WORKBENCH_PrivateData *wpd,
DRW_shgroup_hair_create_sub(ob, psys, md, grp, NULL);
}
+static const CustomData *workbench_mesh_get_loop_custom_data(const Mesh *mesh)
+{
+ if (mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) {
+ BLI_assert(mesh->edit_mesh != NULL);
+ BLI_assert(mesh->edit_mesh->bm != NULL);
+ return &mesh->edit_mesh->bm->ldata;
+ }
+ return &mesh->ldata;
+}
+
+static const CustomData *workbench_mesh_get_vert_custom_data(const Mesh *mesh)
+{
+ if (mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) {
+ BLI_assert(mesh->edit_mesh != NULL);
+ BLI_assert(mesh->edit_mesh->bm != NULL);
+ return &mesh->edit_mesh->bm->vdata;
+ }
+ return &mesh->vdata;
+}
+
/**
* Decide what color-type to draw the object with.
* In some cases it can be overwritten by #workbench_material_setup().
@@ -251,6 +272,8 @@ static eV3DShadingColorType workbench_color_type_get(WORKBENCH_PrivateData *wpd,
{
eV3DShadingColorType color_type = wpd->shading.color_type;
const Mesh *me = (ob->type == OB_MESH) ? ob->data : NULL;
+ const CustomData *ldata = (me == NULL) ? NULL : workbench_mesh_get_loop_custom_data(me);
+ const CustomData *vdata = (me == NULL) ? NULL : workbench_mesh_get_vert_custom_data(me);
const DRWContextState *draw_ctx = DRW_context_state_get();
const bool is_active = (ob == draw_ctx->obact);
@@ -264,19 +287,19 @@ static eV3DShadingColorType workbench_color_type_get(WORKBENCH_PrivateData *wpd,
if (ob->dt < OB_TEXTURE) {
color_type = V3D_SHADING_MATERIAL_COLOR;
}
- else if ((me == NULL) || (me->mloopuv == NULL)) {
+ else if ((me == NULL) || !CustomData_has_layer(ldata, CD_MLOOPUV)) {
/* Disable color mode if data layer is unavailable. */
color_type = V3D_SHADING_MATERIAL_COLOR;
}
}
else if (color_type == V3D_SHADING_VERTEX_COLOR) {
if (U.experimental.use_sculpt_vertex_colors) {
- if ((me == NULL) || !CustomData_has_layer(&me->vdata, CD_PROP_COLOR)) {
+ if ((me == NULL) || !CustomData_has_layer(vdata, CD_PROP_COLOR)) {
color_type = V3D_SHADING_OBJECT_COLOR;
}
}
else {
- if ((me == NULL) || !CustomData_has_layer(&me->ldata, CD_MLOOPCOL)) {
+ if ((me == NULL) || !CustomData_has_layer(ldata, CD_MLOOPCOL)) {
color_type = V3D_SHADING_OBJECT_COLOR;
}
}
@@ -291,13 +314,13 @@ static eV3DShadingColorType workbench_color_type_get(WORKBENCH_PrivateData *wpd,
if (!is_sculpt_pbvh && !is_render) {
/* Force texture or vertex mode if object is in paint mode. */
- if (is_texpaint_mode && me && me->mloopuv) {
+ if (is_texpaint_mode && me && CustomData_has_layer(ldata, CD_MLOOPUV)) {
color_type = V3D_SHADING_TEXTURE_COLOR;
if (r_texpaint_mode) {
*r_texpaint_mode = true;
}
}
- else if (is_vertpaint_mode && me && me->mloopcol) {
+ else if (is_vertpaint_mode && me && CustomData_has_layer(ldata, CD_MLOOPCOL)) {
color_type = V3D_SHADING_VERTEX_COLOR;
}
}
diff --git a/source/blender/draw/engines/workbench/workbench_shader_shared.h b/source/blender/draw/engines/workbench/workbench_shader_shared.h
index 0bfd5957834..c63760a634d 100644
--- a/source/blender/draw/engines/workbench/workbench_shader_shared.h
+++ b/source/blender/draw/engines/workbench/workbench_shader_shared.h
@@ -1,6 +1,6 @@
#ifndef GPU_SHADER
-# include "gpu_shader_shared_utils.h"
+# include "GPU_shader_shared_utils.h"
#endif
#define WORKBENCH_SHADER_SHARED_H
diff --git a/source/blender/draw/intern/DRW_gpu_wrapper.hh b/source/blender/draw/intern/DRW_gpu_wrapper.hh
index 2809661c8c8..d4491223c10 100644
--- a/source/blender/draw/intern/DRW_gpu_wrapper.hh
+++ b/source/blender/draw/intern/DRW_gpu_wrapper.hh
@@ -295,6 +295,10 @@ class UniformArrayBuffer : public detail::UniformCommon<T, len, false> {
/* TODO(@fclem): We should map memory instead. */
this->data_ = (T *)MEM_mallocN_aligned(len * sizeof(T), 16, this->name_);
}
+ ~UniformArrayBuffer()
+ {
+ MEM_freeN(this->data_);
+ }
};
template<
@@ -674,20 +678,20 @@ class Texture : NonCopyable {
if (h == 0) {
return GPU_texture_create_1d(name_, w, mips, format, data);
}
- else if (d == 0) {
+ else if (cubemap) {
if (layered) {
- return GPU_texture_create_1d_array(name_, w, h, mips, format, data);
+ return GPU_texture_create_cube_array(name_, w, d, mips, format, data);
}
else {
- return GPU_texture_create_2d(name_, w, h, mips, format, data);
+ return GPU_texture_create_cube(name_, w, mips, format, data);
}
}
- else if (cubemap) {
+ else if (d == 0) {
if (layered) {
- return GPU_texture_create_cube_array(name_, w, d, mips, format, data);
+ return GPU_texture_create_1d_array(name_, w, h, mips, format, data);
}
else {
- return GPU_texture_create_cube(name_, w, mips, format, data);
+ return GPU_texture_create_2d(name_, w, h, mips, format, data);
}
}
else {
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 8c56d21746d..d531d8ad9f8 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -66,6 +66,15 @@
extern "C" {
#endif
+/* Uncomment to track unused resource bindings. */
+// #define DRW_UNUSED_RESOURCE_TRACKING
+
+#ifdef DRW_UNUSED_RESOURCE_TRACKING
+# define DRW_DEBUG_FILE_LINE_ARGS , const char *file, int line
+#else
+# define DRW_DEBUG_FILE_LINE_ARGS
+#endif
+
struct GPUBatch;
struct GPUMaterial;
struct GPUShader;
@@ -468,6 +477,10 @@ void DRW_shgroup_call_compute(DRWShadingGroup *shgroup,
int groups_x_len,
int groups_y_len,
int groups_z_len);
+/**
+ * \warning this keeps the ref to groups_ref until it actually dispatch.
+ */
+void DRW_shgroup_call_compute_ref(DRWShadingGroup *shgroup, int groups_ref[3]);
void DRW_shgroup_call_procedural_points(DRWShadingGroup *sh, Object *ob, uint point_count);
void DRW_shgroup_call_procedural_lines(DRWShadingGroup *sh, Object *ob, uint line_count);
void DRW_shgroup_call_procedural_triangles(DRWShadingGroup *sh, Object *ob, uint tri_count);
@@ -534,6 +547,11 @@ void DRW_shgroup_stencil_set(DRWShadingGroup *shgroup,
void DRW_shgroup_stencil_mask(DRWShadingGroup *shgroup, uint mask);
/**
+ * Issue a barrier command.
+ */
+void DRW_shgroup_barrier(DRWShadingGroup *shgroup, eGPUBarrier type);
+
+/**
* Issue a clear command.
*/
void DRW_shgroup_clear_framebuffer(DRWShadingGroup *shgroup,
@@ -559,12 +577,12 @@ void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup,
void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup,
const char *name,
struct GPUTexture **tex);
-void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup,
- const char *name,
- const struct GPUUniformBuf *ubo);
-void DRW_shgroup_uniform_block_ref(DRWShadingGroup *shgroup,
- const char *name,
- struct GPUUniformBuf **ubo);
+void DRW_shgroup_uniform_block_ex(DRWShadingGroup *shgroup,
+ const char *name,
+ const struct GPUUniformBuf *ubo DRW_DEBUG_FILE_LINE_ARGS);
+void DRW_shgroup_uniform_block_ref_ex(DRWShadingGroup *shgroup,
+ const char *name,
+ struct GPUUniformBuf **ubo DRW_DEBUG_FILE_LINE_ARGS);
void DRW_shgroup_uniform_float(DRWShadingGroup *shgroup,
const char *name,
const float *value,
@@ -624,9 +642,32 @@ void DRW_shgroup_uniform_vec4_array_copy(DRWShadingGroup *shgroup,
const char *name,
const float (*value)[4],
int arraysize);
-void DRW_shgroup_vertex_buffer(DRWShadingGroup *shgroup,
- const char *name,
- struct GPUVertBuf *vertex_buffer);
+void DRW_shgroup_vertex_buffer_ex(DRWShadingGroup *shgroup,
+ const char *name,
+ struct GPUVertBuf *vertex_buffer DRW_DEBUG_FILE_LINE_ARGS);
+void DRW_shgroup_vertex_buffer_ref_ex(DRWShadingGroup *shgroup,
+ const char *name,
+ struct GPUVertBuf **vertex_buffer DRW_DEBUG_FILE_LINE_ARGS);
+
+#ifdef DRW_UNUSED_RESOURCE_TRACKING
+# define DRW_shgroup_vertex_buffer(shgroup, name, vert) \
+ DRW_shgroup_vertex_buffer_ex(shgroup, name, vert, __FILE__, __LINE__)
+# define DRW_shgroup_vertex_buffer_ref(shgroup, name, vert) \
+ DRW_shgroup_vertex_buffer_ref_ex(shgroup, name, vert, __FILE__, __LINE__)
+# define DRW_shgroup_uniform_block(shgroup, name, ubo) \
+ DRW_shgroup_uniform_block_ex(shgroup, name, ubo, __FILE__, __LINE__)
+# define DRW_shgroup_uniform_block_ref(shgroup, name, ubo) \
+ DRW_shgroup_uniform_block_ref_ex(shgroup, name, ubo, __FILE__, __LINE__)
+#else
+# define DRW_shgroup_vertex_buffer(shgroup, name, vert) \
+ DRW_shgroup_vertex_buffer_ex(shgroup, name, vert)
+# define DRW_shgroup_vertex_buffer_ref(shgroup, name, vert) \
+ DRW_shgroup_vertex_buffer_ref_ex(shgroup, name, vert)
+# define DRW_shgroup_uniform_block(shgroup, name, ubo) \
+ DRW_shgroup_uniform_block_ex(shgroup, name, ubo)
+# define DRW_shgroup_uniform_block_ref(shgroup, name, ubo) \
+ DRW_shgroup_uniform_block_ref_ex(shgroup, name, ubo)
+#endif
bool DRW_shgroup_is_empty(DRWShadingGroup *shgroup);
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index f57921d058c..e7e0e97499f 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -505,8 +505,9 @@ static bool custom_data_match_attribute(const CustomData *custom_data,
int *r_layer_index,
int *r_type)
{
- const int possible_attribute_types[6] = {
+ const int possible_attribute_types[7] = {
CD_PROP_BOOL,
+ CD_PROP_INT8,
CD_PROP_INT32,
CD_PROP_FLOAT,
CD_PROP_FLOAT2,
@@ -655,6 +656,7 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object,
break;
}
case CD_PROP_BOOL:
+ case CD_PROP_INT8:
case CD_PROP_INT32:
case CD_PROP_FLOAT:
case CD_PROP_FLOAT2:
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index 38cd3ecb9b6..73fd157426c 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -205,8 +205,10 @@ typedef enum {
/* Compute Commands. */
DRW_CMD_COMPUTE = 8,
+ DRW_CMD_COMPUTE_REF = 9,
/* Other Commands */
+ DRW_CMD_BARRIER = 11,
DRW_CMD_CLEAR = 12,
DRW_CMD_DRWSTATE = 13,
DRW_CMD_STENCIL = 14,
@@ -249,6 +251,14 @@ typedef struct DRWCommandCompute {
int groups_z_len;
} DRWCommandCompute;
+typedef struct DRWCommandComputeRef {
+ int *groups_ref;
+} DRWCommandComputeRef;
+
+typedef struct DRWCommandBarrier {
+ eGPUBarrier type;
+} DRWCommandBarrier;
+
typedef struct DRWCommandDrawProcedural {
GPUBatch *batch;
DRWResourceHandle handle;
@@ -286,6 +296,8 @@ typedef union DRWCommand {
DRWCommandDrawInstanceRange instance_range;
DRWCommandDrawProcedural procedural;
DRWCommandCompute compute;
+ DRWCommandComputeRef compute_ref;
+ DRWCommandBarrier barrier;
DRWCommandSetMutableState state;
DRWCommandSetStencil stencil;
DRWCommandSetSelectID select_id;
@@ -314,6 +326,7 @@ typedef enum {
DRW_UNIFORM_BLOCK_REF,
DRW_UNIFORM_TFEEDBACK_TARGET,
DRW_UNIFORM_VERTEX_BUFFER_AS_STORAGE,
+ DRW_UNIFORM_VERTEX_BUFFER_AS_STORAGE_REF,
/** Per drawcall uniforms/UBO */
DRW_UNIFORM_BLOCK_OBMATS,
DRW_UNIFORM_BLOCK_OBINFOS,
@@ -345,6 +358,11 @@ struct DRWUniform {
GPUUniformBuf *block;
GPUUniformBuf **block_ref;
};
+ /* DRW_UNIFORM_VERTEX_BUFFER_AS_STORAGE */
+ union {
+ GPUVertBuf *vertbuf;
+ GPUVertBuf **vertbuf_ref;
+ };
/* DRW_UNIFORM_FLOAT_COPY */
float fvalue[4];
/* DRW_UNIFORM_INT_COPY */
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index f07fc94f5d1..3f299e878c4 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -283,19 +283,45 @@ void DRW_shgroup_uniform_image_ref(DRWShadingGroup *shgroup, const char *name, G
drw_shgroup_uniform_create_ex(shgroup, loc, DRW_UNIFORM_IMAGE_REF, tex, 0, 0, 1);
}
-void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup,
- const char *name,
- const GPUUniformBuf *ubo)
+void DRW_shgroup_uniform_block_ex(DRWShadingGroup *shgroup,
+ const char *name,
+ const GPUUniformBuf *ubo DRW_DEBUG_FILE_LINE_ARGS)
{
BLI_assert(ubo != NULL);
int loc = GPU_shader_get_uniform_block_binding(shgroup->shader, name);
+ if (loc == -1) {
+#ifdef DRW_UNUSED_RESOURCE_TRACKING
+ printf("%s:%d: Unable to locate binding of shader uniform buffer object: %s.\n",
+ file,
+ line,
+ name);
+#else
+ /* TODO(@fclem): Would be good to have, but eevee has too much of this for the moment. */
+ // BLI_assert_msg(0, "Unable to locate binding of shader uniform buffer objects.");
+#endif
+ return;
+ }
drw_shgroup_uniform_create_ex(shgroup, loc, DRW_UNIFORM_BLOCK, ubo, 0, 0, 1);
}
-void DRW_shgroup_uniform_block_ref(DRWShadingGroup *shgroup, const char *name, GPUUniformBuf **ubo)
+void DRW_shgroup_uniform_block_ref_ex(DRWShadingGroup *shgroup,
+ const char *name,
+ GPUUniformBuf **ubo DRW_DEBUG_FILE_LINE_ARGS)
{
BLI_assert(ubo != NULL);
int loc = GPU_shader_get_uniform_block_binding(shgroup->shader, name);
+ if (loc == -1) {
+#ifdef DRW_UNUSED_RESOURCE_TRACKING
+ printf("%s:%d: Unable to locate binding of shader uniform buffer object: %s.\n",
+ file,
+ line,
+ name);
+#else
+ /* TODO(@fclem): Would be good to have, but eevee has too much of this for the moment. */
+ // BLI_assert_msg(0, "Unable to locate binding of shader uniform buffer objects.");
+#endif
+ return;
+ }
drw_shgroup_uniform_create_ex(shgroup, loc, DRW_UNIFORM_BLOCK_REF, ubo, 0, 0, 1);
}
@@ -447,19 +473,46 @@ void DRW_shgroup_uniform_vec4_array_copy(DRWShadingGroup *shgroup,
}
}
-void DRW_shgroup_vertex_buffer(DRWShadingGroup *shgroup,
- const char *name,
- GPUVertBuf *vertex_buffer)
+void DRW_shgroup_vertex_buffer_ex(DRWShadingGroup *shgroup,
+ const char *name,
+ GPUVertBuf *vertex_buffer DRW_DEBUG_FILE_LINE_ARGS)
{
int location = GPU_shader_get_ssbo(shgroup->shader, name);
if (location == -1) {
+#ifdef DRW_UNUSED_RESOURCE_TRACKING
+ printf("%s:%d: Unable to locate binding of shader storage buffer object: %s.\n",
+ file,
+ line,
+ name);
+#else
BLI_assert_msg(0, "Unable to locate binding of shader storage buffer objects.");
+#endif
return;
}
drw_shgroup_uniform_create_ex(
shgroup, location, DRW_UNIFORM_VERTEX_BUFFER_AS_STORAGE, vertex_buffer, 0, 0, 1);
}
+void DRW_shgroup_vertex_buffer_ref_ex(DRWShadingGroup *shgroup,
+ const char *name,
+ GPUVertBuf **vertex_buffer DRW_DEBUG_FILE_LINE_ARGS)
+{
+ int location = GPU_shader_get_ssbo(shgroup->shader, name);
+ if (location == -1) {
+#ifdef DRW_UNUSED_RESOURCE_TRACKING
+ printf("%s:%d: Unable to locate binding of shader storage buffer object: %s.\n",
+ file,
+ line,
+ name);
+#else
+ BLI_assert_msg(0, "Unable to locate binding of shader storage buffer objects.");
+#endif
+ return;
+ }
+ drw_shgroup_uniform_create_ex(
+ shgroup, location, DRW_UNIFORM_VERTEX_BUFFER_AS_STORAGE_REF, vertex_buffer, 0, 0, 1);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -730,6 +783,18 @@ static void drw_command_compute(DRWShadingGroup *shgroup,
cmd->groups_z_len = groups_z_len;
}
+static void drw_command_compute_ref(DRWShadingGroup *shgroup, int groups_ref[3])
+{
+ DRWCommandComputeRef *cmd = drw_command_create(shgroup, DRW_CMD_COMPUTE_REF);
+ cmd->groups_ref = groups_ref;
+}
+
+static void drw_command_barrier(DRWShadingGroup *shgroup, eGPUBarrier type)
+{
+ DRWCommandBarrier *cmd = drw_command_create(shgroup, DRW_CMD_BARRIER);
+ cmd->type = type;
+}
+
static void drw_command_draw_procedural(DRWShadingGroup *shgroup,
GPUBatch *batch,
DRWResourceHandle handle,
@@ -855,6 +920,20 @@ void DRW_shgroup_call_compute(DRWShadingGroup *shgroup,
drw_command_compute(shgroup, groups_x_len, groups_y_len, groups_z_len);
}
+void DRW_shgroup_call_compute_ref(DRWShadingGroup *shgroup, int groups_ref[3])
+{
+ BLI_assert(GPU_compute_shader_support());
+
+ drw_command_compute_ref(shgroup, groups_ref);
+}
+
+void DRW_shgroup_barrier(DRWShadingGroup *shgroup, eGPUBarrier type)
+{
+ BLI_assert(GPU_compute_shader_support());
+
+ drw_command_barrier(shgroup, type);
+}
+
static void drw_shgroup_call_procedural_add_ex(DRWShadingGroup *shgroup,
GPUBatch *geom,
Object *ob,
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index 2095a8483d6..a579403975f 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -662,8 +662,11 @@ static void draw_update_uniforms(DRWShadingGroup *shgroup,
*use_tfeedback = GPU_shader_transform_feedback_enable(shgroup->shader,
((GPUVertBuf *)uni->pvalue));
break;
+ case DRW_UNIFORM_VERTEX_BUFFER_AS_STORAGE_REF:
+ GPU_vertbuf_bind_as_ssbo(*uni->vertbuf_ref, uni->location);
+ break;
case DRW_UNIFORM_VERTEX_BUFFER_AS_STORAGE:
- GPU_vertbuf_bind_as_ssbo((GPUVertBuf *)uni->pvalue, uni->location);
+ GPU_vertbuf_bind_as_ssbo(uni->vertbuf, uni->location);
break;
/* Legacy/Fallback support. */
case DRW_UNIFORM_BASE_INSTANCE:
@@ -1049,6 +1052,15 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
cmd->compute.groups_y_len,
cmd->compute.groups_z_len);
break;
+ case DRW_CMD_COMPUTE_REF:
+ GPU_compute_dispatch(shgroup->shader,
+ cmd->compute_ref.groups_ref[0],
+ cmd->compute_ref.groups_ref[1],
+ cmd->compute_ref.groups_ref[2]);
+ break;
+ case DRW_CMD_BARRIER:
+ GPU_memory_barrier(cmd->barrier.type);
+ break;
}
}
diff --git a/source/blender/draw/intern/draw_shader_shared.h b/source/blender/draw/intern/draw_shader_shared.h
index 133ffdbd636..fba8f91b2f6 100644
--- a/source/blender/draw/intern/draw_shader_shared.h
+++ b/source/blender/draw/intern/draw_shader_shared.h
@@ -1,6 +1,6 @@
#ifndef GPU_SHADER
-# include "gpu_shader_shared_utils.h"
+# include "GPU_shader_shared_utils.h"
#endif
#define DRW_SHADER_SHARED_H
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc
index 4dcd821e607..b27633405b9 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc
@@ -99,6 +99,7 @@ static uint gpu_component_size_for_attribute_type(CustomDataType type)
{
switch (type) {
case CD_PROP_BOOL:
+ case CD_PROP_INT8:
case CD_PROP_INT32:
case CD_PROP_FLOAT: {
/* TODO(@kevindietrich): should be 1 when scalar attributes conversion is handled by us. See
@@ -326,6 +327,10 @@ static void extract_attr_init(const MeshRenderData *mr,
extract_attr_generic<bool, float3>(mr, vbo, request);
break;
}
+ case CD_PROP_INT8: {
+ extract_attr_generic<int8_t, float3>(mr, vbo, request);
+ break;
+ }
case CD_PROP_INT32: {
extract_attr_generic<int32_t, float3>(mr, vbo, request);
break;
@@ -378,6 +383,10 @@ static void extract_attr_init_subdiv(const DRWSubdivCache *subdiv_cache,
extract_attr_generic<bool, float3>(mr, src_data, request);
break;
}
+ case CD_PROP_INT8: {
+ extract_attr_generic<int8_t, float3>(mr, src_data, request);
+ break;
+ }
case CD_PROP_INT32: {
extract_attr_generic<int32_t, float3>(mr, src_data, request);
break;
diff --git a/source/blender/draw/intern/shaders/common_view_lib.glsl b/source/blender/draw/intern/shaders/common_view_lib.glsl
index d4d18b95238..2ac157ad208 100644
--- a/source/blender/draw/intern/shaders/common_view_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_view_lib.glsl
@@ -1,5 +1,5 @@
/* Temporary until we fully make the switch. */
-#ifndef DRW_SHADER_SHARED_H
+#ifndef USE_GPU_SHADER_CREATE_INFO
# define DRW_RESOURCE_CHUNK_LEN 512
@@ -24,7 +24,13 @@ layout(std140) uniform viewBlock
vec4 CameraTexCoFactors;
};
-#endif /* DRW_SHADER_SHARED_H */
+#endif /* USE_GPU_SHADER_CREATE_INFO */
+
+#ifdef USE_GPU_SHADER_CREATE_INFO
+# ifndef DRW_RESOURCE_CHUNK_LEN
+# error "Missing draw_view additional create info on shader create info"
+# endif
+#endif
#define ViewNear (ViewVecs[0].w)
#define ViewFar (ViewVecs[1].w)
diff --git a/source/blender/draw/intern/shaders/draw_view_info.hh b/source/blender/draw/intern/shaders/draw_view_info.hh
index 479527379cf..f9dcf291f95 100644
--- a/source/blender/draw/intern/shaders/draw_view_info.hh
+++ b/source/blender/draw/intern/shaders/draw_view_info.hh
@@ -30,7 +30,7 @@ GPU_SHADER_CREATE_INFO(draw_resource_id_uniform)
/**
* Declare a resource handle that identify a unique object.
- * Requires draw_resource_id[_constant].
+ * Requires draw_resource_id[_uniform].
*/
GPU_SHADER_CREATE_INFO(draw_resource_handle)
.define("resource_handle (drw_resourceChunk * DRW_RESOURCE_CHUNK_LEN + resource_id)")
diff --git a/source/blender/editors/gpencil/gpencil_sculpt_paint.c b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
index 802f9f72e49..29f34cc2d67 100644
--- a/source/blender/editors/gpencil/gpencil_sculpt_paint.c
+++ b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
@@ -317,7 +317,7 @@ static void gpencil_update_geometry(bGPdata *gpd)
}
}
if (changed) {
- DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
+ DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
}
}
@@ -1360,7 +1360,7 @@ static void gpencil_sculpt_brush_init_stroke(bContext *C, tGP_BrushEditData *gso
BKE_gpencil_frame_addcopy(gpl, cfra);
BKE_gpencil_tag_full_update(gpd, gpl, NULL, NULL);
/* Need tag to recalculate evaluated data to avoid crashes. */
- DEG_id_tag_update(&gso->gpd->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
+ DEG_id_tag_update(&gso->gpd->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
}
}
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 33c6e382f50..260e3dabc25 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -2073,8 +2073,9 @@ static void UI_OT_tree_view_drop(wmOperatorType *ot)
/** \name UI Tree-View Item Rename Operator
*
* General purpose renaming operator for tree-views. Thanks to this, to add a rename button to
- * context menus for example, tree-view API users don't have to implement own renaming operators
- * with the same logic as they already have for their #ui::AbstractTreeViewItem::rename() override.
+ * context menus for example, tree-view API users don't have to implement their own renaming
+ * operators with the same logic as they already have for their #ui::AbstractTreeViewItem::rename()
+ * override.
*
* \{ */
diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c
index 1fe538eca5d..bf3fa6e62d4 100644
--- a/source/blender/editors/interface/interface_style.c
+++ b/source/blender/editors/interface/interface_style.c
@@ -453,15 +453,6 @@ void uiStyleInit(void)
printf("%s: error, no fonts available\n", __func__);
}
}
- else {
- /* ? just for speed to initialize?
- * Yes, this build the glyph cache and create
- * the texture.
- */
- BLF_size(font->blf_id, 11.0f * U.pixelsize, U.dpi);
- BLF_size(font->blf_id, 12.0f * U.pixelsize, U.dpi);
- BLF_size(font->blf_id, 14.0f * U.pixelsize, U.dpi);
- }
}
if (style == NULL) {
@@ -485,8 +476,6 @@ void uiStyleInit(void)
blf_mono_font = BLF_load_mono_default(unique);
}
- BLF_size(blf_mono_font, 12.0f * U.pixelsize, 72);
-
/* Set default flags based on UI preferences (not render fonts) */
{
const int flag_disable = (BLF_MONOCHROME | BLF_HINTING_NONE | BLF_HINTING_SLIGHT |
@@ -529,8 +518,6 @@ void uiStyleInit(void)
const bool unique = true;
blf_mono_font_render = BLF_load_mono_default(unique);
}
-
- BLF_size(blf_mono_font_render, 12.0f * U.pixelsize, 72);
}
void UI_fontstyle_set(const uiFontStyle *fs)
diff --git a/source/blender/editors/render/render_internal.cc b/source/blender/editors/render/render_internal.cc
index 8e9a052381c..d04e45e4ccb 100644
--- a/source/blender/editors/render/render_internal.cc
+++ b/source/blender/editors/render/render_internal.cc
@@ -90,7 +90,7 @@ struct RenderJob {
Scene *scene;
ViewLayer *single_layer;
Scene *current_scene;
- /* TODO(sergey): Should not be needed once engine will have own
+ /* TODO(sergey): Should not be needed once engine will have its own
* depsgraph and copy-on-write will be implemented.
*/
Depsgraph *depsgraph;
@@ -981,7 +981,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
rj->scene = scene;
rj->current_scene = rj->scene;
rj->single_layer = single_layer;
- /* TODO(sergey): Render engine should be using own depsgraph.
+ /* TODO(sergey): Render engine should be using its own depsgraph.
*
* NOTE: Currently is only used by ED_update_for_newframe() at the end of the render, so no
* need to ensure evaluation here. */
diff --git a/source/blender/editors/render/render_preview.cc b/source/blender/editors/render/render_preview.cc
index df078bbd890..c1c75e485f7 100644
--- a/source/blender/editors/render/render_preview.cc
+++ b/source/blender/editors/render/render_preview.cc
@@ -767,7 +767,7 @@ struct ObjectPreviewData {
/* The main for the preview, not of the current file. */
Main *pr_main;
/* Copy of the object to create the preview for. The copy is for thread safety (and to insert
- * it into an own main). */
+ * it into its own main). */
Object *object;
/* Current frame. */
int cfra;
diff --git a/source/blender/editors/space_graph/graph_slider_ops.c b/source/blender/editors/space_graph/graph_slider_ops.c
index 44a8817fe7c..cfaea33605a 100644
--- a/source/blender/editors/space_graph/graph_slider_ops.c
+++ b/source/blender/editors/space_graph/graph_slider_ops.c
@@ -483,7 +483,7 @@ static char *decimate_desc(bContext *UNUSED(C), wmOperatorType *UNUSED(op), Poin
if (RNA_enum_get(ptr, "mode") == DECIM_ERROR) {
return BLI_strdup(
- TIP_("Decimate F-Curves by specifying how much it can deviate from the original curve"));
+ TIP_("Decimate F-Curves by specifying how much they can deviate from the original curve"));
}
/* Use default description. */
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc b/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc
index f4b5ff819ed..d9837b7c1a6 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc
@@ -127,6 +127,28 @@ class SpreadsheetLayoutDrawer : public SpreadsheetDrawer {
UI_but_drawflag_disable(but, UI_BUT_TEXT_LEFT);
UI_but_drawflag_enable(but, UI_BUT_TEXT_RIGHT);
}
+ if (data.type().is<int8_t>()) {
+ const int8_t value = data.get<int8_t>(real_index);
+ const std::string value_str = std::to_string(value);
+ uiBut *but = uiDefIconTextBut(params.block,
+ UI_BTYPE_LABEL,
+ 0,
+ ICON_NONE,
+ value_str.c_str(),
+ params.xmin,
+ params.ymin,
+ params.width,
+ params.height,
+ nullptr,
+ 0,
+ 0,
+ 0,
+ 0,
+ nullptr);
+ /* Right-align Integers. */
+ UI_but_drawflag_disable(but, UI_BUT_TEXT_LEFT);
+ UI_but_drawflag_enable(but, UI_BUT_TEXT_RIGHT);
+ }
else if (data.type().is<float>()) {
const float value = data.get<float>(real_index);
std::stringstream ss;
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc
index 56722104b4f..c409defd3f4 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc
@@ -243,7 +243,7 @@ static void spreadsheet_filter_panel_draw(const bContext *C, Panel *panel)
uiItemR(layout, filter_ptr, "value_string", 0, IFACE_("Value"), ICON_NONE);
break;
case SPREADSHEET_VALUE_TYPE_UNKNOWN:
- uiItemL(layout, IFACE_("Unkown column type"), ICON_ERROR);
+ uiItemL(layout, IFACE_("Unknown column type"), ICON_ERROR);
break;
}
}
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 6aa00da7501..51107499d3f 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -244,7 +244,6 @@ void ED_view3d_shade_update(Main *bmain, View3D *v3d, ScrArea *area)
for (region = area->regionbase.first; region; region = region->next) {
if ((region->regiontype == RGN_TYPE_WINDOW) && region->regiondata) {
ED_view3d_stop_render_preview(wm, region);
- break;
}
}
}
diff --git a/source/blender/editors/space_view3d/view3d_navigate.c b/source/blender/editors/space_view3d/view3d_navigate.c
index 692a3005607..98eef94d5fb 100644
--- a/source/blender/editors/space_view3d/view3d_navigate.c
+++ b/source/blender/editors/space_view3d/view3d_navigate.c
@@ -143,21 +143,6 @@ void calctrackballvec(const rcti *rect, const int event_xy[2], float r_dir[3])
}
}
-void viewops_data_alloc(bContext *C, wmOperator *op)
-{
- ViewOpsData *vod = MEM_callocN(sizeof(ViewOpsData), "viewops data");
-
- /* store data */
- op->customdata = vod;
- vod->bmain = CTX_data_main(C);
- vod->depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- vod->scene = CTX_data_scene(C);
- vod->area = CTX_wm_area(C);
- vod->region = CTX_wm_region(C);
- vod->v3d = vod->area->spacedata.first;
- vod->rv3d = vod->region->regiondata;
-}
-
void view3d_orbit_apply_dyn_ofs(float r_ofs[3],
const float ofs_old[3],
const float viewquat_old[4],
@@ -289,13 +274,20 @@ enum eViewOpsFlag viewops_flag_from_prefs(void)
(U.uiflag & USER_DEPTH_NAVIGATE) != 0);
}
-void viewops_data_create(bContext *C,
- wmOperator *op,
- const wmEvent *event,
- enum eViewOpsFlag viewops_flag)
+ViewOpsData *viewops_data_create(bContext *C, const wmEvent *event, enum eViewOpsFlag viewops_flag)
{
- Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- ViewOpsData *vod = op->customdata;
+ ViewOpsData *vod = MEM_callocN(sizeof(ViewOpsData), __func__);
+
+ /* Store data. */
+ vod->bmain = CTX_data_main(C);
+ vod->depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ vod->scene = CTX_data_scene(C);
+ vod->area = CTX_wm_area(C);
+ vod->region = CTX_wm_region(C);
+ vod->v3d = vod->area->spacedata.first;
+ vod->rv3d = vod->region->regiondata;
+
+ Depsgraph *depsgraph = vod->depsgraph;
RegionView3D *rv3d = vod->rv3d;
/* Could do this more nicely. */
@@ -427,13 +419,14 @@ void viewops_data_create(bContext *C,
}
rv3d->rflag |= RV3D_NAVIGATING;
+
+ return vod;
}
-void viewops_data_free(bContext *C, wmOperator *op)
+void viewops_data_free(bContext *C, ViewOpsData *vod)
{
ARegion *region;
- if (op->customdata) {
- ViewOpsData *vod = op->customdata;
+ if (vod) {
region = vod->region;
vod->rv3d->rflag &= ~RV3D_NAVIGATING;
@@ -446,7 +439,6 @@ void viewops_data_free(bContext *C, wmOperator *op)
}
MEM_freeN(vod);
- op->customdata = NULL;
}
else {
region = CTX_wm_region(C);
@@ -1569,13 +1561,12 @@ static int viewpan_invoke(bContext *C, wmOperator *op, const wmEvent *event)
y = 25;
}
- viewops_data_alloc(C, op);
- viewops_data_create(C, op, event, (viewops_flag_from_prefs() & ~VIEWOPS_FLAG_ORBIT_SELECT));
- ViewOpsData *vod = op->customdata;
+ ViewOpsData *vod = viewops_data_create(
+ C, event, (viewops_flag_from_prefs() & ~VIEWOPS_FLAG_ORBIT_SELECT));
viewmove_apply(vod, vod->prev.event_xy[0] + x, vod->prev.event_xy[1] + y);
- viewops_data_free(C, op);
+ viewops_data_free(C, vod);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_view3d/view3d_navigate.h b/source/blender/editors/space_view3d/view3d_navigate.h
index c44f1f94708..792d2a83bc2 100644
--- a/source/blender/editors/space_view3d/view3d_navigate.h
+++ b/source/blender/editors/space_view3d/view3d_navigate.h
@@ -82,7 +82,7 @@ enum eViewOpsFlag {
/** Generic View Operator Custom-Data */
typedef struct ViewOpsData {
- /** Context pointers (assigned by #viewops_data_alloc). */
+ /** Context pointers (assigned by #viewops_data_create). */
struct Main *bmain;
struct Scene *scene;
struct ScrArea *area;
@@ -169,16 +169,14 @@ void view3d_operator_properties_common(struct wmOperatorType *ot, const enum eV3
/**
* Allocate and fill in context pointers for #ViewOpsData
*/
-void viewops_data_alloc(struct bContext *C, struct wmOperator *op);
-void viewops_data_free(struct bContext *C, struct wmOperator *op);
+void viewops_data_free(struct bContext *C, ViewOpsData *vod);
/**
- * Calculate the values for #ViewOpsData
+ * Allocate, fill in context pointers and calculate the values for #ViewOpsData
*/
-void viewops_data_create(struct bContext *C,
- struct wmOperator *op,
- const struct wmEvent *event,
- enum eViewOpsFlag viewops_flag);
+ViewOpsData *viewops_data_create(struct bContext *C,
+ const struct wmEvent *event,
+ enum eViewOpsFlag viewops_flag);
void VIEW3D_OT_view_all(struct wmOperatorType *ot);
void VIEW3D_OT_view_selected(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_view3d/view3d_navigate_dolly.c b/source/blender/editors/space_view3d/view3d_navigate_dolly.c
index 7273ec7f7fa..02783c2a244 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_dolly.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_dolly.c
@@ -174,7 +174,8 @@ static int viewdolly_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
if (ret & OPERATOR_FINISHED) {
- viewops_data_free(C, op);
+ viewops_data_free(C, vod);
+ op->customdata = NULL;
}
return ret;
@@ -225,7 +226,8 @@ static int viewdolly_exec(bContext *C, wmOperator *op)
ED_region_tag_redraw(region);
- viewops_data_free(C, op);
+ viewops_data_free(C, op->customdata);
+ op->customdata = NULL;
return OPERATOR_FINISHED;
}
@@ -239,9 +241,13 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_CANCELLED;
}
- /* makes op->customdata */
- viewops_data_alloc(C, op);
- vod = op->customdata;
+ const bool use_cursor_init = RNA_boolean_get(op->ptr, "use_cursor_init");
+
+ vod = op->customdata = viewops_data_create(
+ C,
+ event,
+ (viewops_flag_from_prefs() & ~VIEWOPS_FLAG_ORBIT_SELECT) |
+ (use_cursor_init ? VIEWOPS_FLAG_USE_MOUSE_INIT : 0));
ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->region);
@@ -259,14 +265,6 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
ED_region_tag_redraw(vod->region);
}
- const bool use_cursor_init = RNA_boolean_get(op->ptr, "use_cursor_init");
-
- viewops_data_create(C,
- op,
- event,
- (viewops_flag_from_prefs() & ~VIEWOPS_FLAG_ORBIT_SELECT) |
- (use_cursor_init ? VIEWOPS_FLAG_USE_MOUSE_INIT : 0));
-
/* if one or the other zoom position aren't set, set from event */
if (!RNA_struct_property_is_set(op->ptr, "mx") || !RNA_struct_property_is_set(op->ptr, "my")) {
RNA_int_set(op->ptr, "mx", event->xy[0]);
@@ -296,7 +294,8 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
viewdolly_apply(vod, event->prev_xy, (U.uiflag & USER_ZOOM_INVERT) == 0);
- viewops_data_free(C, op);
+ viewops_data_free(C, op->customdata);
+ op->customdata = NULL;
return OPERATOR_FINISHED;
}
@@ -309,7 +308,8 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void viewdolly_cancel(bContext *C, wmOperator *op)
{
- viewops_data_free(C, op);
+ viewops_data_free(C, op->customdata);
+ op->customdata = NULL;
}
void VIEW3D_OT_dolly(wmOperatorType *ot)
diff --git a/source/blender/editors/space_view3d/view3d_navigate_fly.c b/source/blender/editors/space_view3d/view3d_navigate_fly.c
index 05f6a10d89f..940616eec1f 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_fly.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_fly.c
@@ -1103,9 +1103,9 @@ static int fly_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
else
#endif /* WITH_INPUT_NDOF */
- if (event->type == TIMER && event->customdata == fly->timer) {
- flyApply(C, fly, false);
- }
+ if (event->type == TIMER && event->customdata == fly->timer) {
+ flyApply(C, fly, false);
+ }
do_draw |= fly->redraw;
diff --git a/source/blender/editors/space_view3d/view3d_navigate_move.c b/source/blender/editors/space_view3d/view3d_navigate_move.c
index e23767923b1..90acf20d24f 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_move.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_move.c
@@ -119,7 +119,8 @@ static int viewmove_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
if (ret & OPERATOR_FINISHED) {
- viewops_data_free(C, op);
+ viewops_data_free(C, op->customdata);
+ op->customdata = NULL;
}
return ret;
@@ -131,13 +132,11 @@ static int viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *event)
const bool use_cursor_init = RNA_boolean_get(op->ptr, "use_cursor_init");
- /* makes op->customdata */
- viewops_data_alloc(C, op);
- viewops_data_create(C,
- op,
- event,
- (viewops_flag_from_prefs() & ~VIEWOPS_FLAG_ORBIT_SELECT) |
- (use_cursor_init ? VIEWOPS_FLAG_USE_MOUSE_INIT : 0));
+ vod = op->customdata = viewops_data_create(
+ C,
+ event,
+ (viewops_flag_from_prefs() & ~VIEWOPS_FLAG_ORBIT_SELECT) |
+ (use_cursor_init ? VIEWOPS_FLAG_USE_MOUSE_INIT : 0));
vod = op->customdata;
ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->region);
@@ -147,7 +146,8 @@ static int viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *event)
viewmove_apply(
vod, 2 * event->xy[0] - event->prev_xy[0], 2 * event->xy[1] - event->prev_xy[1]);
- viewops_data_free(C, op);
+ viewops_data_free(C, op->customdata);
+ op->customdata = NULL;
return OPERATOR_FINISHED;
}
@@ -160,7 +160,8 @@ static int viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void viewmove_cancel(bContext *C, wmOperator *op)
{
- viewops_data_free(C, op);
+ viewops_data_free(C, op->customdata);
+ op->customdata = NULL;
}
void VIEW3D_OT_move(wmOperatorType *ot)
diff --git a/source/blender/editors/space_view3d/view3d_navigate_ndof.c b/source/blender/editors/space_view3d/view3d_navigate_ndof.c
index 69394b36e54..285d5c02db2 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_ndof.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_ndof.c
@@ -378,9 +378,8 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
const wmNDOFMotionData *ndof = event->customdata;
- viewops_data_alloc(C, op);
- viewops_data_create(C, op, event, (viewops_flag_from_prefs() & ~VIEWOPS_FLAG_DEPTH_NAVIGATE));
- vod = op->customdata;
+ vod = op->customdata = viewops_data_create(
+ C, event, (viewops_flag_from_prefs() & ~VIEWOPS_FLAG_DEPTH_NAVIGATE));
ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->region);
@@ -418,7 +417,8 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
ED_region_tag_redraw(vod->region);
- viewops_data_free(C, op);
+ viewops_data_free(C, op->customdata);
+ op->customdata = NULL;
return OPERATOR_FINISHED;
}
@@ -458,10 +458,8 @@ static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev
const wmNDOFMotionData *ndof = event->customdata;
- viewops_data_alloc(C, op);
- viewops_data_create(C, op, event, (viewops_flag_from_prefs() & ~VIEWOPS_FLAG_DEPTH_NAVIGATE));
-
- vod = op->customdata;
+ vod = op->customdata = viewops_data_create(
+ C, event, (viewops_flag_from_prefs() & ~VIEWOPS_FLAG_DEPTH_NAVIGATE));
ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->region);
@@ -533,7 +531,8 @@ static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev
ED_region_tag_redraw(vod->region);
- viewops_data_free(C, op);
+ viewops_data_free(C, op->customdata);
+ op->customdata = NULL;
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_view3d/view3d_navigate_roll.c b/source/blender/editors/space_view3d/view3d_navigate_roll.c
index c01346919a9..c9bfdc4412a 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_roll.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_roll.c
@@ -107,7 +107,8 @@ static int viewroll_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* Note this does not remove auto-keys on locked cameras. */
copy_qt_qt(vod->rv3d->viewquat, vod->init.quat);
ED_view3d_camera_lock_sync(vod->depsgraph, vod->v3d, vod->rv3d);
- viewops_data_free(C, op);
+ viewops_data_free(C, op->customdata);
+ op->customdata = NULL;
return OPERATOR_CANCELLED;
}
else if (event->type == vod->init.event_type && event->val == KM_RELEASE) {
@@ -130,7 +131,8 @@ static int viewroll_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
if (ret & OPERATOR_FINISHED) {
- viewops_data_free(C, op);
+ viewops_data_free(C, op->customdata);
+ op->customdata = NULL;
}
return ret;
@@ -201,11 +203,13 @@ static int viewroll_exec(bContext *C, wmOperator *op)
.dyn_ofs = dyn_ofs_pt,
});
- viewops_data_free(C, op);
+ viewops_data_free(C, op->customdata);
+ op->customdata = NULL;
return OPERATOR_FINISHED;
}
- viewops_data_free(C, op);
+ viewops_data_free(C, op->customdata);
+ op->customdata = NULL;
return OPERATOR_CANCELLED;
}
@@ -220,9 +224,7 @@ static int viewroll_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
else {
/* makes op->customdata */
- viewops_data_alloc(C, op);
- viewops_data_create(C, op, event, viewops_flag_from_prefs());
- vod = op->customdata;
+ vod = op->customdata = viewops_data_create(C, event, viewops_flag_from_prefs());
vod->init.dial = BLI_dial_init((const float[2]){BLI_rcti_cent_x(&vod->region->winrct),
BLI_rcti_cent_y(&vod->region->winrct)},
FLT_EPSILON);
@@ -237,7 +239,8 @@ static int viewroll_invoke(bContext *C, wmOperator *op, const wmEvent *event)
vod->init.event_xy[0] = vod->prev.event_xy[0] = event->xy[0];
viewroll_apply(vod, event->prev_xy[0], event->prev_xy[1]);
- viewops_data_free(C, op);
+ viewops_data_free(C, op->customdata);
+ op->customdata = NULL;
return OPERATOR_FINISHED;
}
@@ -250,7 +253,8 @@ static int viewroll_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void viewroll_cancel(bContext *C, wmOperator *op)
{
- viewops_data_free(C, op);
+ viewops_data_free(C, op->customdata);
+ op->customdata = NULL;
}
void VIEW3D_OT_view_roll(wmOperatorType *ot)
diff --git a/source/blender/editors/space_view3d/view3d_navigate_rotate.c b/source/blender/editors/space_view3d/view3d_navigate_rotate.c
index c65acde0ad0..c3730b3b3b1 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_rotate.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_rotate.c
@@ -370,7 +370,8 @@ static int viewrotate_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
if (ret & OPERATOR_FINISHED) {
- viewops_data_free(C, op);
+ viewops_data_free(C, op->customdata);
+ op->customdata = NULL;
}
return ret;
@@ -383,17 +384,14 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
const bool use_cursor_init = RNA_boolean_get(op->ptr, "use_cursor_init");
/* makes op->customdata */
- viewops_data_alloc(C, op);
- vod = op->customdata;
+ vod = op->customdata = viewops_data_create(
+ C,
+ event,
+ viewops_flag_from_prefs() | VIEWOPS_FLAG_PERSP_ENSURE |
+ (use_cursor_init ? VIEWOPS_FLAG_USE_MOUSE_INIT : 0));
ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->region);
- viewops_data_create(C,
- op,
- event,
- viewops_flag_from_prefs() | VIEWOPS_FLAG_PERSP_ENSURE |
- (use_cursor_init ? VIEWOPS_FLAG_USE_MOUSE_INIT : 0));
-
if (ELEM(event->type, MOUSEPAN, MOUSEROTATE)) {
/* Rotate direction we keep always same */
int event_xy[2];
@@ -414,7 +412,8 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
viewrotate_apply(vod, event_xy);
- viewops_data_free(C, op);
+ viewops_data_free(C, op->customdata);
+ op->customdata = NULL;
return OPERATOR_FINISHED;
}
@@ -427,7 +426,8 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void viewrotate_cancel(bContext *C, wmOperator *op)
{
- viewops_data_free(C, op);
+ viewops_data_free(C, op->customdata);
+ op->customdata = NULL;
}
void VIEW3D_OT_rotate(wmOperatorType *ot)
diff --git a/source/blender/editors/space_view3d/view3d_navigate_walk.c b/source/blender/editors/space_view3d/view3d_navigate_walk.c
index 4d6df2b655a..d72fa3cb90f 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_walk.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_walk.c
@@ -1487,9 +1487,9 @@ static int walk_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
else
#endif /* WITH_INPUT_NDOF */
- if (event->type == TIMER && event->customdata == walk->timer) {
- walkApply(C, walk, false);
- }
+ if (event->type == TIMER && event->customdata == walk->timer) {
+ walkApply(C, walk, false);
+ }
do_draw |= walk->redraw;
diff --git a/source/blender/editors/space_view3d/view3d_navigate_zoom.c b/source/blender/editors/space_view3d/view3d_navigate_zoom.c
index 24a977f7521..a6c7d06c079 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_zoom.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_zoom.c
@@ -418,7 +418,8 @@ static int viewzoom_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
if (ret & OPERATOR_FINISHED) {
- viewops_data_free(C, op);
+ viewops_data_free(C, op->customdata);
+ op->customdata = NULL;
}
return ret;
@@ -499,7 +500,8 @@ static int viewzoom_exec(bContext *C, wmOperator *op)
ED_region_tag_redraw(region);
- viewops_data_free(C, op);
+ viewops_data_free(C, op->customdata);
+ op->customdata = NULL;
return OPERATOR_FINISHED;
}
@@ -511,14 +513,11 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
const bool use_cursor_init = RNA_boolean_get(op->ptr, "use_cursor_init");
- /* makes op->customdata */
- viewops_data_alloc(C, op);
- viewops_data_create(C,
- op,
- event,
- (viewops_flag_from_prefs() & ~VIEWOPS_FLAG_ORBIT_SELECT) |
- (use_cursor_init ? VIEWOPS_FLAG_USE_MOUSE_INIT : 0));
- vod = op->customdata;
+ vod = op->customdata = viewops_data_create(
+ C,
+ event,
+ (viewops_flag_from_prefs() & ~VIEWOPS_FLAG_ORBIT_SELECT) |
+ (use_cursor_init ? VIEWOPS_FLAG_USE_MOUSE_INIT : 0));
ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->region);
@@ -549,7 +548,8 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
(use_cursor_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)));
ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true);
- viewops_data_free(C, op);
+ viewops_data_free(C, op->customdata);
+ op->customdata = NULL;
return OPERATOR_FINISHED;
}
@@ -569,7 +569,8 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void viewzoom_cancel(bContext *C, wmOperator *op)
{
- viewops_data_free(C, op);
+ viewops_data_free(C, op->customdata);
+ op->customdata = NULL;
}
void VIEW3D_OT_zoom(wmOperatorType *ot)
diff --git a/source/blender/functions/FN_field.hh b/source/blender/functions/FN_field.hh
index e869927c33b..e42feac1644 100644
--- a/source/blender/functions/FN_field.hh
+++ b/source/blender/functions/FN_field.hh
@@ -87,8 +87,7 @@ class FieldNode {
public:
FieldNode(FieldNodeType node_type);
-
- virtual ~FieldNode() = default;
+ virtual ~FieldNode();
virtual const CPPType &output_cpp_type(int output_index) const = 0;
@@ -230,6 +229,7 @@ class FieldOperation : public FieldNode {
public:
FieldOperation(std::shared_ptr<const MultiFunction> function, Vector<GField> inputs = {});
FieldOperation(const MultiFunction &function, Vector<GField> inputs = {});
+ ~FieldOperation();
Span<GField> inputs() const;
const MultiFunction &multi_function() const;
@@ -259,6 +259,7 @@ class FieldInput : public FieldNode {
public:
FieldInput(const CPPType &type, std::string debug_name = "");
+ ~FieldInput();
/**
* Get the value of this specific input based on the given context. The returned virtual array,
diff --git a/source/blender/functions/intern/cpp_types.cc b/source/blender/functions/intern/cpp_types.cc
index 0bbfbc8cb10..7f1eb8bc1a7 100644
--- a/source/blender/functions/intern/cpp_types.cc
+++ b/source/blender/functions/intern/cpp_types.cc
@@ -31,6 +31,7 @@ MAKE_CPP_TYPE(float3, blender::float3, CPPTypeFlags::BasicType)
MAKE_CPP_TYPE(float4x4, blender::float4x4, CPPTypeFlags::BasicType)
MAKE_CPP_TYPE(int32, int32_t, CPPTypeFlags::BasicType)
+MAKE_CPP_TYPE(int8, int8_t, CPPTypeFlags::BasicType)
MAKE_CPP_TYPE(uint32, uint32_t, CPPTypeFlags::BasicType)
MAKE_CPP_TYPE(uint8, uint8_t, CPPTypeFlags::BasicType)
@@ -44,6 +45,7 @@ MAKE_FIELD_CPP_TYPE(Float2Field, float2);
MAKE_FIELD_CPP_TYPE(Float3Field, float3);
MAKE_FIELD_CPP_TYPE(ColorGeometry4fField, blender::ColorGeometry4f);
MAKE_FIELD_CPP_TYPE(BoolField, bool);
+MAKE_FIELD_CPP_TYPE(Int8Field, int8_t);
MAKE_FIELD_CPP_TYPE(Int32Field, int32_t);
MAKE_FIELD_CPP_TYPE(StringField, std::string);
diff --git a/source/blender/functions/intern/field.cc b/source/blender/functions/intern/field.cc
index d6b83c42294..fe3041b8602 100644
--- a/source/blender/functions/intern/field.cc
+++ b/source/blender/functions/intern/field.cc
@@ -571,6 +571,13 @@ bool IndexFieldInput::is_equal_to(const fn::FieldNode &other) const
}
/* --------------------------------------------------------------------
+ * FieldNode.
+ */
+
+/* Avoid generating the destructor in every translation unit. */
+FieldNode::~FieldNode() = default;
+
+/* --------------------------------------------------------------------
* FieldOperation.
*/
@@ -581,6 +588,9 @@ FieldOperation::FieldOperation(std::shared_ptr<const MultiFunction> function,
owned_function_ = std::move(function);
}
+/* Avoid generating the destructor in every translation unit. */
+FieldOperation::~FieldOperation() = default;
+
/**
* Returns the field inputs used by all the provided fields.
* This tries to reuse an existing #FieldInputs whenever possible to avoid copying it.
@@ -655,6 +665,9 @@ FieldInput::FieldInput(const CPPType &type, std::string debug_name)
field_inputs_ = std::move(field_inputs);
}
+/* Avoid generating the destructor in every translation unit. */
+FieldInput::~FieldInput() = default;
+
/* --------------------------------------------------------------------
* FieldConstant.
*/
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 2b6b28bd649..cffea5e9dcc 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -375,7 +375,7 @@ set(GLSL_SRC
shaders/gpu_shader_common_obinfos_lib.glsl
- intern/gpu_shader_shared_utils.h
+ GPU_shader_shared_utils.h
)
set(GLSL_C)
diff --git a/source/blender/gpu/GPU_debug.h b/source/blender/gpu/GPU_debug.h
index 9796ac63272..18a35f9c71a 100644
--- a/source/blender/gpu/GPU_debug.h
+++ b/source/blender/gpu/GPU_debug.h
@@ -31,6 +31,8 @@
extern "C" {
#endif
+#define GPU_DEBUG_SHADER_COMPILATION_GROUP "Shader Compilation"
+
void GPU_debug_group_begin(const char *name);
void GPU_debug_group_end(void);
/**
diff --git a/source/blender/gpu/GPU_shader_shared.h b/source/blender/gpu/GPU_shader_shared.h
index eeca7ee6caa..636a8f53ba6 100644
--- a/source/blender/gpu/GPU_shader_shared.h
+++ b/source/blender/gpu/GPU_shader_shared.h
@@ -22,7 +22,7 @@
*/
#ifndef USE_GPU_SHADER_CREATE_INFO
-# include "intern/gpu_shader_shared_utils.h"
+# include "GPU_shader_shared_utils.h"
#endif
struct NodeLinkData {
diff --git a/source/blender/gpu/intern/gpu_shader_shared_utils.h b/source/blender/gpu/GPU_shader_shared_utils.h
index 0d283fb1e66..0d283fb1e66 100644
--- a/source/blender/gpu/intern/gpu_shader_shared_utils.h
+++ b/source/blender/gpu/GPU_shader_shared_utils.h
diff --git a/source/blender/gpu/GPU_state.h b/source/blender/gpu/GPU_state.h
index 22cd7eab927..bd52b8321bb 100644
--- a/source/blender/gpu/GPU_state.h
+++ b/source/blender/gpu/GPU_state.h
@@ -37,11 +37,14 @@ ENUM_OPERATORS(eGPUWriteMask, GPU_WRITE_COLOR)
typedef enum eGPUBarrier {
GPU_BARRIER_NONE = 0,
- GPU_BARRIER_SHADER_IMAGE_ACCESS = (1 << 0),
- GPU_BARRIER_TEXTURE_FETCH = (1 << 1),
- GPU_BARRIER_SHADER_STORAGE = (1 << 2),
- GPU_BARRIER_VERTEX_ATTRIB_ARRAY = (1 << 3),
- GPU_BARRIER_ELEMENT_ARRAY = (1 << 4),
+ GPU_BARRIER_COMMAND = (1 << 0),
+ GPU_BARRIER_FRAMEBUFFER = (1 << 1),
+ GPU_BARRIER_SHADER_IMAGE_ACCESS = (1 << 2),
+ GPU_BARRIER_SHADER_STORAGE = (1 << 3),
+ GPU_BARRIER_TEXTURE_FETCH = (1 << 4),
+ GPU_BARRIER_TEXTURE_UPDATE = (1 << 5),
+ GPU_BARRIER_VERTEX_ATTRIB_ARRAY = (1 << 6),
+ GPU_BARRIER_ELEMENT_ARRAY = (1 << 7),
} eGPUBarrier;
ENUM_OPERATORS(eGPUBarrier, GPU_BARRIER_ELEMENT_ARRAY)
diff --git a/source/blender/gpu/intern/gpu_framebuffer_private.hh b/source/blender/gpu/intern/gpu_framebuffer_private.hh
index a936e889e57..e7505258d2a 100644
--- a/source/blender/gpu/intern/gpu_framebuffer_private.hh
+++ b/source/blender/gpu/intern/gpu_framebuffer_private.hh
@@ -43,8 +43,9 @@ typedef enum GPUAttachmentType : int {
GPU_FB_COLOR_ATTACHMENT3,
GPU_FB_COLOR_ATTACHMENT4,
GPU_FB_COLOR_ATTACHMENT5,
- /* Number of maximum output slots.
- * We support 6 outputs for now (usually we wouldn't need more to preserve fill rate). */
+ GPU_FB_COLOR_ATTACHMENT6,
+ GPU_FB_COLOR_ATTACHMENT7,
+ /* Number of maximum output slots. */
/* Keep in mind that GL max is GL_MAX_DRAW_BUFFERS and is at least 8, corresponding to
* the maximum number of COLOR attachments specified by glDrawBuffers. */
GPU_FB_MAX_ATTACHMENT,
diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc
index 2e924925ab8..7db34917ad7 100644
--- a/source/blender/gpu/intern/gpu_shader.cc
+++ b/source/blender/gpu/intern/gpu_shader.cc
@@ -26,6 +26,7 @@
#include "BLI_string_utils.h"
#include "GPU_capabilities.h"
+#include "GPU_debug.h"
#include "GPU_matrix.h"
#include "GPU_platform.h"
@@ -273,6 +274,8 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
const_cast<ShaderCreateInfo &>(info).finalize();
+ GPU_debug_group_begin(GPU_DEBUG_SHADER_COMPILATION_GROUP);
+
/* At least a vertex shader and a fragment shader are required, or only a compute shader. */
if (info.compute_source_.is_empty()) {
if (info.vertex_source_.is_empty()) {
@@ -301,20 +304,22 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
std::string defines = shader->defines_declare(info);
std::string resources = shader->resources_declare(info);
- char *shader_shared_utils = nullptr;
defines += "#define USE_GPU_SHADER_CREATE_INFO\n";
- Vector<char *> typedefs;
- for (auto filename : info.typedef_sources_) {
- typedefs.append(gpu_shader_dependency_get_source(filename.c_str()));
+ Vector<const char *> typedefs;
+ if (!info.typedef_sources_.is_empty() || !info.typedef_source_generated.empty()) {
+ typedefs.append(gpu_shader_dependency_get_source("GPU_shader_shared_utils.h").c_str());
}
- if (!typedefs.is_empty()) {
- shader_shared_utils = gpu_shader_dependency_get_source("gpu_shader_shared_utils.h");
+ if (!info.typedef_source_generated.empty()) {
+ typedefs.append(info.typedef_source_generated.c_str());
+ }
+ for (auto filename : info.typedef_sources_) {
+ typedefs.append(gpu_shader_dependency_get_source(filename).c_str());
}
if (!info.vertex_source_.is_empty()) {
- char *code = gpu_shader_dependency_get_resolved_source(info.vertex_source_.c_str());
+ auto code = gpu_shader_dependency_get_resolved_source(info.vertex_source_);
std::string interface = shader->vertex_interface_declare(info);
Vector<const char *> sources;
@@ -324,23 +329,18 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
sources.append("#define USE_GEOMETRY_SHADER\n");
}
sources.append(defines.c_str());
- if (!typedefs.is_empty()) {
- sources.append(shader_shared_utils);
- }
- for (auto *types : typedefs) {
- sources.append(types);
- }
+ sources.extend(typedefs);
sources.append(resources.c_str());
sources.append(interface.c_str());
- sources.append(code);
+ sources.extend(code);
+ sources.extend(info.dependencies_generated);
+ sources.append(info.vertex_source_generated.c_str());
shader->vertex_shader_from_glsl(sources);
-
- free(code);
}
if (!info.fragment_source_.is_empty()) {
- char *code = gpu_shader_dependency_get_resolved_source(info.fragment_source_.c_str());
+ auto code = gpu_shader_dependency_get_resolved_source(info.fragment_source_);
std::string interface = shader->fragment_interface_declare(info);
Vector<const char *> sources;
@@ -350,23 +350,18 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
sources.append("#define USE_GEOMETRY_SHADER\n");
}
sources.append(defines.c_str());
- if (!typedefs.is_empty()) {
- sources.append(shader_shared_utils);
- }
- for (auto *types : typedefs) {
- sources.append(types);
- }
+ sources.extend(typedefs);
sources.append(resources.c_str());
sources.append(interface.c_str());
- sources.append(code);
+ sources.extend(code);
+ sources.extend(info.dependencies_generated);
+ sources.append(info.fragment_source_generated.c_str());
shader->fragment_shader_from_glsl(sources);
-
- free(code);
}
if (!info.geometry_source_.is_empty()) {
- char *code = gpu_shader_dependency_get_resolved_source(info.geometry_source_.c_str());
+ auto code = gpu_shader_dependency_get_resolved_source(info.geometry_source_);
std::string layout = shader->geometry_layout_declare(info);
std::string interface = shader->geometry_interface_declare(info);
@@ -374,58 +369,38 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
standard_defines(sources);
sources.append("#define GPU_GEOMETRY_SHADER\n");
sources.append(defines.c_str());
- if (!typedefs.is_empty()) {
- sources.append(shader_shared_utils);
- }
- for (auto *types : typedefs) {
- sources.append(types);
- }
+ sources.extend(typedefs);
sources.append(resources.c_str());
sources.append(layout.c_str());
sources.append(interface.c_str());
- sources.append(code);
+ sources.extend(code);
shader->geometry_shader_from_glsl(sources);
-
- free(code);
}
if (!info.compute_source_.is_empty()) {
- char *code = gpu_shader_dependency_get_resolved_source(info.compute_source_.c_str());
+ auto code = gpu_shader_dependency_get_resolved_source(info.compute_source_);
std::string layout = shader->compute_layout_declare(info);
Vector<const char *> sources;
standard_defines(sources);
sources.append("#define GPU_COMPUTE_SHADER\n");
sources.append(defines.c_str());
- if (!typedefs.is_empty()) {
- sources.append(shader_shared_utils);
- }
- for (auto *types : typedefs) {
- sources.append(types);
- }
+ sources.extend(typedefs);
sources.append(resources.c_str());
sources.append(layout.c_str());
- sources.append(code);
+ sources.extend(code);
shader->compute_shader_from_glsl(sources);
-
- free(code);
- }
-
- for (auto *types : typedefs) {
- free(types);
- }
-
- if (shader_shared_utils) {
- free(shader_shared_utils);
}
if (!shader->finalize(&info)) {
delete shader;
+ GPU_debug_group_end();
return nullptr;
}
+ GPU_debug_group_end();
return wrap(shader);
}
diff --git a/source/blender/gpu/intern/gpu_shader_create_info.cc b/source/blender/gpu/intern/gpu_shader_create_info.cc
index 1464a7ade24..fe0304828c2 100644
--- a/source/blender/gpu/intern/gpu_shader_create_info.cc
+++ b/source/blender/gpu/intern/gpu_shader_create_info.cc
@@ -55,6 +55,8 @@ void ShaderCreateInfo::finalize()
}
finalized_ = true;
+ Set<StringRefNull> deps_merged;
+
for (auto &info_name : additional_infos_) {
const ShaderCreateInfo &info = *reinterpret_cast<const ShaderCreateInfo *>(
gpu_shader_create_info_get(info_name.c_str()));
@@ -62,11 +64,6 @@ void ShaderCreateInfo::finalize()
/* Recursive. */
const_cast<ShaderCreateInfo &>(info).finalize();
-#if 0 /* Enabled for debugging merging. TODO(fclem) exception handling and error reporting in \
- console. */
- std::cout << "Merging : " << info_name << " > " << name_ << std::endl;
-#endif
-
interface_names_size_ += info.interface_names_size_;
vertex_inputs_.extend(info.vertex_inputs_);
@@ -83,37 +80,76 @@ void ShaderCreateInfo::finalize()
validate(info);
+ auto assert_no_overlap = [&](const bool test, const StringRefNull error) {
+ if (!test) {
+ std::cout << name_ << ": Validation failed while merging " << info.name_ << " : ";
+ std::cout << error << std::endl;
+ BLI_assert(0);
+ }
+ };
+
+ if (!deps_merged.add(info.name_)) {
+ assert_no_overlap(false, "additional info already merged via another info");
+ }
+
if (info.compute_layout_.local_size_x != -1) {
- compute_layout_.local_size_x = info.compute_layout_.local_size_x;
- compute_layout_.local_size_y = info.compute_layout_.local_size_y;
- compute_layout_.local_size_z = info.compute_layout_.local_size_z;
+ assert_no_overlap(compute_layout_.local_size_x == -1, "Compute layout already defined");
+ compute_layout_ = info.compute_layout_;
}
if (!info.vertex_source_.is_empty()) {
- BLI_assert(vertex_source_.is_empty());
+ assert_no_overlap(vertex_source_.is_empty(), "Vertex source already existing");
vertex_source_ = info.vertex_source_;
}
if (!info.geometry_source_.is_empty()) {
- BLI_assert(geometry_source_.is_empty());
+ assert_no_overlap(geometry_source_.is_empty(), "Geometry source already existing");
geometry_source_ = info.geometry_source_;
geometry_layout_ = info.geometry_layout_;
}
if (!info.fragment_source_.is_empty()) {
- BLI_assert(fragment_source_.is_empty());
+ assert_no_overlap(fragment_source_.is_empty(), "Fragment source already existing");
fragment_source_ = info.fragment_source_;
}
if (!info.compute_source_.is_empty()) {
- BLI_assert(compute_source_.is_empty());
+ assert_no_overlap(compute_source_.is_empty(), "Compute source already existing");
compute_source_ = info.compute_source_;
}
do_static_compilation_ = do_static_compilation_ || info.do_static_compilation_;
}
+
+ if (auto_resource_location_) {
+ int images = 0, samplers = 0, ubos = 0, ssbos = 0;
+
+ auto set_resource_slot = [&](Resource &res) {
+ switch (res.bind_type) {
+ case Resource::BindType::UNIFORM_BUFFER:
+ res.slot = ubos++;
+ break;
+ case Resource::BindType::STORAGE_BUFFER:
+ res.slot = ssbos++;
+ break;
+ case Resource::BindType::SAMPLER:
+ res.slot = samplers++;
+ break;
+ case Resource::BindType::IMAGE:
+ res.slot = images++;
+ break;
+ }
+ };
+
+ for (auto &res : batch_resources_) {
+ set_resource_slot(res);
+ }
+ for (auto &res : pass_resources_) {
+ set_resource_slot(res);
+ }
+ }
}
void ShaderCreateInfo::validate(const ShaderCreateInfo &other_info)
{
- {
+ if (!auto_resource_location_) {
/* Check same bind-points usage in OGL. */
Set<int> images, samplers, ubos, ssbos;
@@ -133,26 +169,26 @@ void ShaderCreateInfo::validate(const ShaderCreateInfo &other_info)
};
auto print_error_msg = [&](const Resource &res) {
- std::cerr << name_ << ": Validation failed : Overlapping ";
+ std::cout << name_ << ": Validation failed : Overlapping ";
switch (res.bind_type) {
case Resource::BindType::UNIFORM_BUFFER:
- std::cerr << "Uniform Buffer " << res.uniformbuf.name;
+ std::cout << "Uniform Buffer " << res.uniformbuf.name;
break;
case Resource::BindType::STORAGE_BUFFER:
- std::cerr << "Storage Buffer " << res.storagebuf.name;
+ std::cout << "Storage Buffer " << res.storagebuf.name;
break;
case Resource::BindType::SAMPLER:
- std::cerr << "Sampler " << res.sampler.name;
+ std::cout << "Sampler " << res.sampler.name;
break;
case Resource::BindType::IMAGE:
- std::cerr << "Image " << res.image.name;
+ std::cout << "Image " << res.image.name;
break;
default:
- std::cerr << "Unknown Type";
+ std::cout << "Unknown Type";
break;
}
- std::cerr << " (" << res.slot << ") while merging " << other_info.name_ << std::endl;
+ std::cout << " (" << res.slot << ") while merging " << other_info.name_ << std::endl;
};
for (auto &res : batch_resources_) {
@@ -212,14 +248,10 @@ void gpu_shader_create_info_init()
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()));
+ info->builtins_ |= gpu_shader_dependency_get_builtins(info->vertex_source_);
+ info->builtins_ |= gpu_shader_dependency_get_builtins(info->fragment_source_);
+ info->builtins_ |= gpu_shader_dependency_get_builtins(info->geometry_source_);
+ info->builtins_ |= gpu_shader_dependency_get_builtins(info->compute_source_);
}
}
diff --git a/source/blender/gpu/intern/gpu_shader_create_info.hh b/source/blender/gpu/intern/gpu_shader_create_info.hh
index 736a8ed0590..dafa741977c 100644
--- a/source/blender/gpu/intern/gpu_shader_create_info.hh
+++ b/source/blender/gpu/intern/gpu_shader_create_info.hh
@@ -30,8 +30,11 @@
#include "BLI_string_ref.hh"
#include "BLI_vector.hh"
+#include "GPU_material.h"
#include "GPU_texture.h"
+#include <iostream>
+
namespace blender::gpu::shader {
#ifndef GPU_SHADER_CREATE_INFO
@@ -62,6 +65,59 @@ enum class Type {
BOOL,
};
+/* All of these functions is a bit out of place */
+static inline Type to_type(const eGPUType type)
+{
+ switch (type) {
+ case GPU_FLOAT:
+ return Type::FLOAT;
+ case GPU_VEC2:
+ return Type::VEC2;
+ case GPU_VEC3:
+ return Type::VEC3;
+ case GPU_VEC4:
+ return Type::VEC4;
+ case GPU_MAT3:
+ return Type::MAT3;
+ case GPU_MAT4:
+ return Type::MAT4;
+ default:
+ BLI_assert_msg(0, "Error: Cannot convert eGPUType to shader::Type.");
+ return Type::FLOAT;
+ }
+}
+
+static inline std::ostream &operator<<(std::ostream &stream, const Type type)
+{
+ switch (type) {
+ case Type::FLOAT:
+ return stream << "float";
+ case Type::VEC2:
+ return stream << "vec2";
+ case Type::VEC3:
+ return stream << "vec3";
+ case Type::VEC4:
+ return stream << "vec4";
+ case Type::MAT3:
+ return stream << "mat3";
+ case Type::MAT4:
+ return stream << "mat4";
+ default:
+ BLI_assert(0);
+ return stream;
+ }
+}
+
+static inline std::ostream &operator<<(std::ostream &stream, const eGPUType type)
+{
+ switch (type) {
+ case GPU_CLOSURE:
+ return stream << "Closure";
+ default:
+ return stream << to_type(type);
+ }
+}
+
enum class BuiltinBits {
NONE = 0,
/**
@@ -74,7 +130,7 @@ enum class BuiltinBits {
GLOBAL_INVOCATION_ID = (1 << 5),
INSTANCE_ID = (1 << 6),
/**
- * Allow setting the target layer when the output is a layered framebuffer.
+ * Allow setting the target layer when the output is a layered frame-buffer.
* \note Emulated through geometry shader on older hardware.
*/
LAYER = (1 << 7),
@@ -229,6 +285,8 @@ struct ShaderCreateInfo {
bool do_static_compilation_ = false;
/** If true, all additionally linked create info will be merged into this one. */
bool finalized_ = false;
+ /** If true, all resources will have an automatic location assigned. */
+ bool auto_resource_location_ = false;
/**
* Maximum length of all the resource names including each null terminator.
* Only for names used by gpu::ShaderInterface.
@@ -236,11 +294,36 @@ struct ShaderCreateInfo {
size_t interface_names_size_ = 0;
/** Manually set builtins. */
BuiltinBits builtins_ = BuiltinBits::NONE;
+ /** Manually set generated code. */
+ std::string vertex_source_generated = "";
+ std::string fragment_source_generated = "";
+ std::string typedef_source_generated = "";
+ /** Manually set generated dependencies. */
+ Vector<const char *, 0> dependencies_generated;
+
+#define TEST_EQUAL(a, b, _member) \
+ if (!((a)._member == (b)._member)) { \
+ return false; \
+ }
+
+#define TEST_VECTOR_EQUAL(a, b, _vector) \
+ TEST_EQUAL(a, b, _vector.size()); \
+ for (auto i : _vector.index_range()) { \
+ TEST_EQUAL(a, b, _vector[i]); \
+ }
struct VertIn {
int index;
Type type;
StringRefNull name;
+
+ bool operator==(const VertIn &b)
+ {
+ TEST_EQUAL(*this, b, index);
+ TEST_EQUAL(*this, b, type);
+ TEST_EQUAL(*this, b, name);
+ return true;
+ }
};
Vector<VertIn> vertex_inputs_;
@@ -250,6 +333,15 @@ struct ShaderCreateInfo {
PrimitiveOut primitive_out;
/** Set to -1 by default to check if used. */
int max_vertices = -1;
+
+ bool operator==(const GeometryStageLayout &b)
+ {
+ TEST_EQUAL(*this, b, primitive_in);
+ TEST_EQUAL(*this, b, invocations);
+ TEST_EQUAL(*this, b, primitive_out);
+ TEST_EQUAL(*this, b, max_vertices);
+ return true;
+ }
};
GeometryStageLayout geometry_layout_;
@@ -257,8 +349,15 @@ struct ShaderCreateInfo {
int local_size_x = -1;
int local_size_y = -1;
int local_size_z = -1;
- };
+ bool operator==(const ComputeStageLayout &b)
+ {
+ TEST_EQUAL(*this, b, local_size_x);
+ TEST_EQUAL(*this, b, local_size_y);
+ TEST_EQUAL(*this, b, local_size_z);
+ return true;
+ }
+ };
ComputeStageLayout compute_layout_;
struct FragOut {
@@ -266,6 +365,15 @@ struct ShaderCreateInfo {
Type type;
DualBlend blend;
StringRefNull name;
+
+ bool operator==(const FragOut &b)
+ {
+ TEST_EQUAL(*this, b, index);
+ TEST_EQUAL(*this, b, type);
+ TEST_EQUAL(*this, b, blend);
+ TEST_EQUAL(*this, b, name);
+ return true;
+ }
};
Vector<FragOut> fragment_outputs_;
@@ -311,6 +419,35 @@ struct ShaderCreateInfo {
};
Resource(BindType type, int _slot) : bind_type(type), slot(_slot){};
+
+ bool operator==(const Resource &b)
+ {
+ TEST_EQUAL(*this, b, bind_type);
+ TEST_EQUAL(*this, b, slot);
+ switch (bind_type) {
+ case UNIFORM_BUFFER:
+ TEST_EQUAL(*this, b, uniformbuf.type_name);
+ TEST_EQUAL(*this, b, uniformbuf.name);
+ break;
+ case STORAGE_BUFFER:
+ TEST_EQUAL(*this, b, storagebuf.qualifiers);
+ TEST_EQUAL(*this, b, storagebuf.type_name);
+ TEST_EQUAL(*this, b, storagebuf.name);
+ break;
+ case SAMPLER:
+ TEST_EQUAL(*this, b, sampler.type);
+ TEST_EQUAL(*this, b, sampler.sampler);
+ TEST_EQUAL(*this, b, sampler.name);
+ break;
+ case IMAGE:
+ TEST_EQUAL(*this, b, image.format);
+ TEST_EQUAL(*this, b, image.type);
+ TEST_EQUAL(*this, b, image.qualifiers);
+ TEST_EQUAL(*this, b, image.name);
+ break;
+ }
+ return true;
+ }
};
/**
* Resources are grouped by frequency of change.
@@ -327,6 +464,14 @@ struct ShaderCreateInfo {
Type type;
StringRefNull name;
int array_size;
+
+ bool operator==(const PushConst &b)
+ {
+ TEST_EQUAL(*this, b, type);
+ TEST_EQUAL(*this, b, name);
+ TEST_EQUAL(*this, b, array_size);
+ return true;
+ }
};
Vector<PushConst> push_constants_;
@@ -554,6 +699,12 @@ struct ShaderCreateInfo {
return *(Self *)this;
}
+ Self &auto_resource_location(bool value)
+ {
+ auto_resource_location_ = value;
+ return *(Self *)this;
+ }
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -624,6 +775,77 @@ struct ShaderCreateInfo {
void validate(const ShaderCreateInfo &other_info);
/** \} */
+
+ /* -------------------------------------------------------------------- */
+ /** \name Operators.
+ *
+ * \{ */
+
+ /* Comparison operator for GPUPass cache. We only compare if it will create the same shader code.
+ * So we do not compare name and some other internal stuff. */
+ bool operator==(const ShaderCreateInfo &b)
+ {
+ TEST_EQUAL(*this, b, builtins_);
+ TEST_EQUAL(*this, b, vertex_source_generated);
+ TEST_EQUAL(*this, b, fragment_source_generated);
+ TEST_EQUAL(*this, b, typedef_source_generated);
+ TEST_VECTOR_EQUAL(*this, b, vertex_inputs_);
+ TEST_EQUAL(*this, b, geometry_layout_);
+ TEST_EQUAL(*this, b, compute_layout_);
+ TEST_VECTOR_EQUAL(*this, b, fragment_outputs_);
+ TEST_VECTOR_EQUAL(*this, b, pass_resources_);
+ TEST_VECTOR_EQUAL(*this, b, batch_resources_);
+ TEST_VECTOR_EQUAL(*this, b, vertex_out_interfaces_);
+ TEST_VECTOR_EQUAL(*this, b, geometry_out_interfaces_);
+ TEST_VECTOR_EQUAL(*this, b, push_constants_);
+ TEST_VECTOR_EQUAL(*this, b, typedef_sources_);
+ TEST_EQUAL(*this, b, vertex_source_);
+ TEST_EQUAL(*this, b, geometry_source_);
+ TEST_EQUAL(*this, b, fragment_source_);
+ TEST_EQUAL(*this, b, compute_source_);
+ TEST_VECTOR_EQUAL(*this, b, additional_infos_);
+ TEST_VECTOR_EQUAL(*this, b, defines_);
+ return true;
+ }
+
+ /** Debug print */
+ friend std::ostream &operator<<(std::ostream &stream, const ShaderCreateInfo &info)
+ {
+ /* TODO(@fclem): Complete print. */
+
+ auto print_resource = [&](const Resource &res) {
+ switch (res.bind_type) {
+ case Resource::BindType::UNIFORM_BUFFER:
+ stream << "UNIFORM_BUFFER(" << res.slot << ", " << res.uniformbuf.name << ")"
+ << std::endl;
+ break;
+ case Resource::BindType::STORAGE_BUFFER:
+ stream << "STORAGE_BUFFER(" << res.slot << ", " << res.storagebuf.name << ")"
+ << std::endl;
+ break;
+ case Resource::BindType::SAMPLER:
+ stream << "SAMPLER(" << res.slot << ", " << res.sampler.name << ")" << std::endl;
+ break;
+ case Resource::BindType::IMAGE:
+ stream << "IMAGE(" << res.slot << ", " << res.image.name << ")" << std::endl;
+ break;
+ }
+ };
+
+ /* TODO(@fclem): Order the resources. */
+ for (auto &res : info.batch_resources_) {
+ print_resource(res);
+ }
+ for (auto &res : info.pass_resources_) {
+ print_resource(res);
+ }
+ return stream;
+ }
+
+ /** \} */
+
+#undef TEST_EQUAL
+#undef TEST_VECTOR_EQUAL
};
} // namespace blender::gpu::shader
diff --git a/source/blender/gpu/intern/gpu_shader_dependency.cc b/source/blender/gpu/intern/gpu_shader_dependency.cc
index 0db03c2b636..06ad0817bfb 100644
--- a/source/blender/gpu/intern/gpu_shader_dependency.cc
+++ b/source/blender/gpu/intern/gpu_shader_dependency.cc
@@ -332,14 +332,12 @@ struct GPUSource {
}
/* Returns the final string with all includes done. */
- std::string build() const
+ void build(Vector<const char *> &result) const
{
- std::string str;
for (auto *dep : dependencies) {
- str += dep->source;
+ result.append(dep->source.c_str());
}
- str += source;
- return str;
+ result.append(source.c_str());
}
shader::BuiltinBits builtins_get() const
@@ -383,23 +381,47 @@ void gpu_shader_dependency_exit()
delete g_sources;
}
-uint32_t gpu_shader_dependency_get_builtins(const char *shader_source_name)
+namespace blender::gpu::shader {
+
+BuiltinBits gpu_shader_dependency_get_builtins(const StringRefNull shader_source_name)
{
- if (shader_source_name[0] == '\0') {
- return 0;
+ if (shader_source_name.is_empty()) {
+ return shader::BuiltinBits::NONE;
+ }
+ if (g_sources->contains(shader_source_name) == false) {
+ std::cout << "Error: Could not find \"" << shader_source_name
+ << "\" in the list of registered source.\n";
+ BLI_assert(0);
+ return shader::BuiltinBits::NONE;
}
GPUSource *source = g_sources->lookup(shader_source_name);
- return static_cast<uint32_t>(source->builtins_get());
+ return source->builtins_get();
}
-char *gpu_shader_dependency_get_resolved_source(const char *shader_source_name)
+Vector<const char *> gpu_shader_dependency_get_resolved_source(
+ const StringRefNull shader_source_name)
{
+ Vector<const char *> result;
GPUSource *source = g_sources->lookup(shader_source_name);
- return strdup(source->build().c_str());
+ source->build(result);
+ return result;
}
-char *gpu_shader_dependency_get_source(const char *shader_source_name)
+StringRefNull gpu_shader_dependency_get_source(const StringRefNull shader_source_name)
{
GPUSource *src = g_sources->lookup(shader_source_name);
- return strdup(src->source.c_str());
+ return src->source;
+}
+
+StringRefNull gpu_shader_dependency_get_filename_from_source_string(
+ const StringRefNull source_string)
+{
+ for (auto &source : g_sources->values()) {
+ if (source->source.c_str() == source_string.c_str()) {
+ return source->filename;
+ }
+ }
+ return "";
}
+
+} // namespace blender::gpu::shader
diff --git a/source/blender/gpu/intern/gpu_shader_dependency_private.h b/source/blender/gpu/intern/gpu_shader_dependency_private.h
index 083c38897ce..13261dd2021 100644
--- a/source/blender/gpu/intern/gpu_shader_dependency_private.h
+++ b/source/blender/gpu/intern/gpu_shader_dependency_private.h
@@ -34,12 +34,32 @@ 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);
-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
+
+#ifdef __cplusplus
+
+# include "BLI_string_ref.hh"
+# include "BLI_vector.hh"
+
+# include "gpu_shader_create_info.hh"
+
+namespace blender::gpu::shader {
+
+BuiltinBits gpu_shader_dependency_get_builtins(const StringRefNull source_name);
+
+Vector<const char *> gpu_shader_dependency_get_resolved_source(const StringRefNull source_name);
+StringRefNull gpu_shader_dependency_get_source(const StringRefNull source_name);
+
+/**
+ * \brief Find the name of the file from which the given string was generated.
+ * \return Return filename or empty string.
+ * \note source_string needs to be identical to the one given by gpu_shader_dependency_get_source()
+ */
+StringRefNull gpu_shader_dependency_get_filename_from_source_string(
+ const StringRefNull source_string);
+
+} // namespace blender::gpu::shader
+
+#endif
diff --git a/source/blender/gpu/intern/gpu_shader_interface.hh b/source/blender/gpu/intern/gpu_shader_interface.hh
index 7f99619c98c..514cfc01f09 100644
--- a/source/blender/gpu/intern/gpu_shader_interface.hh
+++ b/source/blender/gpu/intern/gpu_shader_interface.hh
@@ -68,6 +68,7 @@ class ShaderInterface {
uint16_t enabled_ubo_mask_ = 0;
uint8_t enabled_ima_mask_ = 0;
uint64_t enabled_tex_mask_ = 0;
+ uint16_t enabled_ssbo_mask_ = 0;
/** Location of builtin uniforms. Fast access, no lookup needed. */
int32_t builtins_[GPU_NUM_UNIFORMS];
int32_t builtin_blocks_[GPU_NUM_UNIFORM_BLOCKS];
diff --git a/source/blender/gpu/intern/gpu_shader_log.cc b/source/blender/gpu/intern/gpu_shader_log.cc
index 21973cf976a..c879e912c5d 100644
--- a/source/blender/gpu/intern/gpu_shader_log.cc
+++ b/source/blender/gpu/intern/gpu_shader_log.cc
@@ -26,7 +26,9 @@
#include "BLI_dynstr.h"
#include "BLI_string.h"
#include "BLI_string_utils.h"
+#include "BLI_vector.hh"
+#include "gpu_shader_dependency_private.h"
#include "gpu_shader_private.hh"
#include "GPU_platform.h"
@@ -41,6 +43,14 @@ namespace blender::gpu {
/** \name Debug functions
* \{ */
+/* Number of lines before and after the error line to print for compilation errors. */
+#define DEBUG_CONTEXT_LINES 0
+/**
+ * Print dependencies sources list before the shader report.
+ * Useful to debug include order or missing dependencies.
+ */
+#define DEBUG_DEPENDENCIES 0
+
void Shader::print_log(Span<const char *> sources,
char *log,
const char *stage,
@@ -61,6 +71,30 @@ void Shader::print_log(Span<const char *> sources,
BLI_dynstr_appendf(dynstr, "\n");
+#if DEBUG_DEPENDENCIES
+ BLI_dynstr_appendf(
+ dynstr, "%s%sIncluded files (in order):%s\n", info_col, line_prefix, reset_col);
+#endif
+
+ Vector<int64_t> sources_end_line;
+ for (StringRefNull src : sources) {
+ int64_t cursor = 0, line_count = 0;
+ while ((cursor = src.find('\n', cursor) + 1)) {
+ line_count++;
+ }
+ if (sources_end_line.is_empty() == false) {
+ line_count += sources_end_line.last();
+ }
+ sources_end_line.append(line_count);
+#if DEBUG_DEPENDENCIES
+ StringRefNull filename = shader::gpu_shader_dependency_get_filename_from_source_string(src);
+ if (!filename.is_empty()) {
+ BLI_dynstr_appendf(
+ dynstr, "%s%s %s%s\n", info_col, line_prefix, filename.c_str(), reset_col);
+ }
+#endif
+ }
+
char *log_line = log, *line_end;
LogCursor previous_location;
@@ -73,12 +107,32 @@ void Shader::print_log(Span<const char *> sources,
continue;
}
+ /* Silence not useful lines. */
+ StringRef logref = StringRefNull(log_line).substr(0, (size_t)line_end - (size_t)log_line);
+ if (logref.endswith(" shader failed to compile with the following errors:") ||
+ logref.endswith(" No code generated")) {
+ log_line += (size_t)line_end - (size_t)log_line;
+ continue;
+ }
+
GPULogItem log_item;
log_line = parser->parse_line(log_line, log_item);
+ /* Sanitize output. Really bad values can happen when the error line is buggy. */
+ if (log_item.cursor.source >= sources.size()) {
+ log_item.cursor.source = -1;
+ }
+ if (log_item.cursor.row >= sources_end_line.last()) {
+ log_item.cursor.source = -1;
+ log_item.cursor.row = -1;
+ }
+
if (log_item.cursor.row == -1) {
found_line_id = false;
}
+ else if (log_item.source_base_row && log_item.cursor.source > 0) {
+ log_item.cursor.row += sources_end_line[log_item.cursor.source - 1];
+ }
const char *src_line = sources_combined;
@@ -98,15 +152,14 @@ void Shader::print_log(Span<const char *> sources,
/* error_line is 1 based in this case. */
int src_line_index = 1;
while ((src_line_end = strchr(src_line, '\n'))) {
- if (src_line_index == log_item.cursor.row) {
+ if (src_line_index >= log_item.cursor.row) {
found_line_id = true;
break;
}
-/* TODO(@fclem): Make this an option to display N lines before error. */
-#if 0 /* Uncomment to print shader file up to the error line to have more context. */
- BLI_dynstr_appendf(dynstr, "%5d | ", src_line_index);
- BLI_dynstr_nappend(dynstr, src_line, (src_line_end + 1) - src_line);
-#endif
+ if (src_line_index >= log_item.cursor.row - DEBUG_CONTEXT_LINES) {
+ BLI_dynstr_appendf(dynstr, "%5d | ", src_line_index);
+ BLI_dynstr_nappend(dynstr, src_line, (src_line_end + 1) - src_line);
+ }
/* Continue to next line. */
src_line = src_line_end + 1;
src_line_index++;
@@ -129,10 +182,53 @@ void Shader::print_log(Span<const char *> sources,
BLI_dynstr_appendf(dynstr, "^");
}
BLI_dynstr_appendf(dynstr, "\n");
+
+ /* Skip the error line. */
+ src_line = src_line_end + 1;
+ src_line_index++;
+ while ((src_line_end = strchr(src_line, '\n'))) {
+ if (src_line_index > log_item.cursor.row + DEBUG_CONTEXT_LINES) {
+ break;
+ }
+ BLI_dynstr_appendf(dynstr, "%5d | ", src_line_index);
+ BLI_dynstr_nappend(dynstr, src_line, (src_line_end + 1) - src_line);
+ /* Continue to next line. */
+ src_line = src_line_end + 1;
+ src_line_index++;
+ }
}
}
BLI_dynstr_appendf(dynstr, line_prefix);
+ /* Search the correct source index. */
+ int row_in_file = log_item.cursor.row;
+ int source_index = log_item.cursor.source;
+ if (source_index <= 0) {
+ for (auto i : sources_end_line.index_range()) {
+ if (log_item.cursor.row <= sources_end_line[i]) {
+ source_index = i;
+ break;
+ }
+ }
+ }
+ if (source_index > 0) {
+ row_in_file -= sources_end_line[source_index - 1];
+ }
+ /* Print the filename the error line is coming from. */
+ if (source_index > 0) {
+ StringRefNull filename = shader::gpu_shader_dependency_get_filename_from_source_string(
+ sources[source_index]);
+ if (!filename.is_empty()) {
+ BLI_dynstr_appendf(dynstr,
+ "%s%s:%d:%d: %s",
+ info_col,
+ filename.c_str(),
+ row_in_file,
+ log_item.cursor.column + 1,
+ reset_col);
+ }
+ }
+
if (log_item.severity == Severity::Error) {
BLI_dynstr_appendf(dynstr, "%s%s%s: ", err_col, "Error", info_col);
}
diff --git a/source/blender/gpu/intern/gpu_shader_private.hh b/source/blender/gpu/intern/gpu_shader_private.hh
index 3bfecdefba7..93c33811ee0 100644
--- a/source/blender/gpu/intern/gpu_shader_private.hh
+++ b/source/blender/gpu/intern/gpu_shader_private.hh
@@ -120,6 +120,7 @@ struct LogCursor {
struct GPULogItem {
LogCursor cursor;
+ bool source_base_row = false;
Severity severity = Severity::Unknown;
};
diff --git a/source/blender/gpu/intern/gpu_texture_private.hh b/source/blender/gpu/intern/gpu_texture_private.hh
index 73b59b9f06f..3195e98da5e 100644
--- a/source/blender/gpu/intern/gpu_texture_private.hh
+++ b/source/blender/gpu/intern/gpu_texture_private.hh
@@ -451,7 +451,6 @@ inline bool validate_data_format(eGPUTextureFormat tex_format, eGPUDataFormat da
}
}
-/* Definitely not complete, edit according to the gl specification. */
inline eGPUDataFormat to_data_format(eGPUTextureFormat tex_format)
{
switch (tex_format) {
@@ -462,16 +461,27 @@ inline eGPUDataFormat to_data_format(eGPUTextureFormat tex_format)
case GPU_DEPTH24_STENCIL8:
case GPU_DEPTH32F_STENCIL8:
return GPU_DATA_UINT_24_8;
- case GPU_R8UI:
case GPU_R16UI:
- case GPU_RG16UI:
case GPU_R32UI:
+ case GPU_RG16UI:
+ case GPU_RG32UI:
+ case GPU_RGBA16UI:
+ case GPU_RGBA32UI:
return GPU_DATA_UINT;
- case GPU_RG16I:
case GPU_R16I:
+ case GPU_R32I:
+ case GPU_R8I:
+ case GPU_RG16I:
+ case GPU_RG32I:
+ case GPU_RG8I:
+ case GPU_RGBA16I:
+ case GPU_RGBA32I:
+ case GPU_RGBA8I:
return GPU_DATA_INT;
case GPU_R8:
+ case GPU_R8UI:
case GPU_RG8:
+ case GPU_RG8UI:
case GPU_RGBA8:
case GPU_RGBA8UI:
case GPU_SRGB8_A8:
diff --git a/source/blender/gpu/opengl/gl_compute.cc b/source/blender/gpu/opengl/gl_compute.cc
index fa8317dde4a..14164ee181b 100644
--- a/source/blender/gpu/opengl/gl_compute.cc
+++ b/source/blender/gpu/opengl/gl_compute.cc
@@ -28,8 +28,8 @@ namespace blender::gpu {
void GLCompute::dispatch(int group_x_len, int group_y_len, int group_z_len)
{
+ GL_CHECK_RESOURCES("Compute");
glDispatchCompute(group_x_len, group_y_len, group_z_len);
- debug::check_gl_error("Dispatch Compute");
}
} // namespace blender::gpu
diff --git a/source/blender/gpu/opengl/gl_debug.cc b/source/blender/gpu/opengl/gl_debug.cc
index 0a06d9cdb7c..95dea43636d 100644
--- a/source/blender/gpu/opengl/gl_debug.cc
+++ b/source/blender/gpu/opengl/gl_debug.cc
@@ -108,6 +108,11 @@ static void APIENTRY debug_callback(GLenum UNUSED(source),
GPU_debug_get_groups_names(sizeof(debug_groups), debug_groups);
CLG_Severity clog_severity;
+ if (GPU_debug_group_match(GPU_DEBUG_SHADER_COMPILATION_GROUP)) {
+ /** Do not duplicate shader compilation error/warnings. */
+ return;
+ }
+
switch (type) {
case GL_DEBUG_TYPE_ERROR:
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
@@ -191,6 +196,9 @@ void init_gl_callbacks()
void check_gl_error(const char *info)
{
+ if (!(G.debug & G_DEBUG_GPU)) {
+ return;
+ }
GLenum error = glGetError();
#define ERROR_CASE(err) \
@@ -339,7 +347,7 @@ void object_label(GLenum type, GLuint object, const char *name)
char label[64];
SNPRINTF(label, "%s%s%s", to_str_prefix(type), name, to_str_suffix(type));
/* Small convenience for caller. */
- if (ELEM(type, GL_FRAGMENT_SHADER, GL_GEOMETRY_SHADER, GL_VERTEX_SHADER)) {
+ if (ELEM(type, GL_FRAGMENT_SHADER, GL_GEOMETRY_SHADER, GL_VERTEX_SHADER, GL_COMPUTE_SHADER)) {
type = GL_SHADER;
}
if (ELEM(type, GL_UNIFORM_BUFFER)) {
diff --git a/source/blender/gpu/opengl/gl_debug_layer.cc b/source/blender/gpu/opengl/gl_debug_layer.cc
index e624cb9ee46..b82bf10ebe9 100644
--- a/source/blender/gpu/opengl/gl_debug_layer.cc
+++ b/source/blender/gpu/opengl/gl_debug_layer.cc
@@ -82,6 +82,8 @@ DEBUG_FUNC_DECLARE(PFNGLDRAWBUFFERSPROC, void, glDrawBuffers, GLsizei, n, const
DEBUG_FUNC_DECLARE(PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC, void, glDrawElementsInstancedBaseVertexBaseInstance, GLenum, mode, GLsizei, count, GLenum, type, const void *, indices, GLsizei, primcount, GLint, basevertex, GLuint, baseinstance);
DEBUG_FUNC_DECLARE(PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC, void, glDrawElementsInstancedBaseVertex, GLenum, mode, GLsizei, count, GLenum, type, const void *, indices, GLsizei, instancecount, GLint, basevertex);
DEBUG_FUNC_DECLARE(PFNGLENDQUERYPROC, void, glEndQuery, GLenum, target);
+DEBUG_FUNC_DECLARE(PFNGLDISPATCHCOMPUTEPROC, void, glDispatchCompute, GLuint, num_groups_x, GLuint, num_groups_y, GLuint, num_groups_z);
+DEBUG_FUNC_DECLARE(PFNGLDISPATCHCOMPUTEINDIRECTPROC, void, glDispatchComputeIndirect, GLintptr, indirect);
DEBUG_FUNC_DECLARE(PFNGLENDTRANSFORMFEEDBACKPROC, void, glEndTransformFeedback, void);
DEBUG_FUNC_DECLARE(PFNGLFRAMEBUFFERTEXTURE2DPROC, void, glFramebufferTexture2D, GLenum, target, GLenum, attachment, GLenum, textarget, GLuint, texture, GLint, level);
DEBUG_FUNC_DECLARE(PFNGLFRAMEBUFFERTEXTURELAYERPROC, void, glFramebufferTextureLayer, GLenum, target, GLenum, attachment, GLuint, texture, GLint, level, GLint, layer);
@@ -130,6 +132,8 @@ void init_debug_layer()
DEBUG_WRAP(glDeleteSamplers);
DEBUG_WRAP(glDeleteShader);
DEBUG_WRAP(glDeleteVertexArrays);
+ DEBUG_WRAP(glDispatchCompute);
+ DEBUG_WRAP(glDispatchComputeIndirect);
DEBUG_WRAP(glDrawArraysInstanced);
DEBUG_WRAP(glDrawArraysInstancedBaseInstance);
DEBUG_WRAP(glDrawBuffers);
diff --git a/source/blender/gpu/opengl/gl_framebuffer.hh b/source/blender/gpu/opengl/gl_framebuffer.hh
index 9ebe549efe7..00a7676dd3f 100644
--- a/source/blender/gpu/opengl/gl_framebuffer.hh
+++ b/source/blender/gpu/opengl/gl_framebuffer.hh
@@ -141,6 +141,8 @@ static inline GLenum to_gl(const GPUAttachmentType type)
ATTACHMENT(COLOR_ATTACHMENT3);
ATTACHMENT(COLOR_ATTACHMENT4);
ATTACHMENT(COLOR_ATTACHMENT5);
+ ATTACHMENT(COLOR_ATTACHMENT6);
+ ATTACHMENT(COLOR_ATTACHMENT7);
default:
BLI_assert(0);
return GL_COLOR_ATTACHMENT0;
diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc
index 3ab3b11d1f4..9da35a2bc97 100644
--- a/source/blender/gpu/opengl/gl_shader.cc
+++ b/source/blender/gpu/opengl/gl_shader.cc
@@ -85,7 +85,7 @@ static const char *to_string(const Interpolation &interp)
case Interpolation::NO_PERSPECTIVE:
return "noperspective";
default:
- return "unkown";
+ return "unknown";
}
}
@@ -123,6 +123,74 @@ static const char *to_string(const Type &type)
case Type::BOOL:
return "bool";
default:
+ return "unknown";
+ }
+}
+
+static const char *to_string(const eGPUTextureFormat &type)
+{
+ switch (type) {
+ case GPU_RGBA8UI:
+ return "rgba8ui";
+ case GPU_RGBA8I:
+ return "rgba8i";
+ case GPU_RGBA8:
+ return "rgba8";
+ case GPU_RGBA32UI:
+ return "rgba32ui";
+ case GPU_RGBA32I:
+ return "rgba32i";
+ case GPU_RGBA32F:
+ return "rgba32f";
+ case GPU_RGBA16UI:
+ return "rgba16ui";
+ case GPU_RGBA16I:
+ return "rgba16i";
+ case GPU_RGBA16F:
+ return "rgba16f";
+ case GPU_RGBA16:
+ return "rgba16";
+ case GPU_RG8UI:
+ return "rg8ui";
+ case GPU_RG8I:
+ return "rg8i";
+ case GPU_RG8:
+ return "rg8";
+ case GPU_RG32UI:
+ return "rg32ui";
+ case GPU_RG32I:
+ return "rg32i";
+ case GPU_RG32F:
+ return "rg32f";
+ case GPU_RG16UI:
+ return "rg16ui";
+ case GPU_RG16I:
+ return "rg16i";
+ case GPU_RG16F:
+ return "rg16f";
+ case GPU_RG16:
+ return "rg16";
+ case GPU_R8UI:
+ return "r8ui";
+ case GPU_R8I:
+ return "r8i";
+ case GPU_R8:
+ return "r8";
+ case GPU_R32UI:
+ return "r32ui";
+ case GPU_R32I:
+ return "r32i";
+ case GPU_R32F:
+ return "r32f";
+ case GPU_R16UI:
+ return "r16ui";
+ case GPU_R16I:
+ return "r16i";
+ case GPU_R16F:
+ return "r16f";
+ case GPU_R16:
+ return "r16";
+ default:
return "unkown";
}
}
@@ -294,7 +362,7 @@ static void print_resource(std::ostream &os, const ShaderCreateInfo::Resource &r
if (GLContext::explicit_location_support) {
os << "layout(binding = " << res.slot;
if (res.bind_type == ShaderCreateInfo::Resource::BindType::IMAGE) {
- os << ", " << res.image.format;
+ os << ", " << to_string(res.image.format);
}
else if (res.bind_type == ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER) {
os << ", std140";
@@ -451,7 +519,9 @@ std::string GLShader::vertex_interface_declare(const ShaderCreateInfo &info) con
ss << "\n/* Inputs. */\n";
for (const ShaderCreateInfo::VertIn &attr : info.vertex_inputs_) {
- if (GLContext::explicit_location_support) {
+ if (GLContext::explicit_location_support &&
+ /* Fix issue with AMDGPU-PRO + workbench_prepass_mesh_vert.glsl being quantized. */
+ GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_OFFICIAL) == false) {
ss << "layout(location = " << attr.index << ") ";
}
ss << "in " << to_string(attr.type) << " " << attr.name << ";\n";
@@ -736,7 +806,7 @@ static char *glsl_patch_default_get()
STR_CONCAT(patch, slen, "#extension GL_ARB_texture_cube_map_array : enable\n");
STR_CONCAT(patch, slen, "#define GPU_ARB_texture_cube_map_array\n");
}
- if (GLEW_ARB_conservative_depth) {
+ if (!GLEW_VERSION_4_2 && GLEW_ARB_conservative_depth) {
STR_CONCAT(patch, slen, "#extension GL_ARB_conservative_depth : enable\n");
}
if (GPU_shader_image_load_store_support()) {
@@ -759,6 +829,9 @@ static char *glsl_patch_default_get()
/* Vulkan GLSL compat. */
STR_CONCAT(patch, slen, "#define gpu_InstanceIndex (gl_InstanceID + gpu_BaseInstance)\n");
+ /* Array compat. */
+ STR_CONCAT(patch, slen, "#define array(_type) _type[]\n");
+
/* Derivative sign can change depending on implementation. */
STR_CONCATF(patch, slen, "#define DFDX_SIGN %1.1f\n", GLContext::derivative_signs[0]);
STR_CONCATF(patch, slen, "#define DFDY_SIGN %1.1f\n", GLContext::derivative_signs[1]);
diff --git a/source/blender/gpu/opengl/gl_shader_interface.cc b/source/blender/gpu/opengl/gl_shader_interface.cc
index 83016fca8a5..0a31f8dee7f 100644
--- a/source/blender/gpu/opengl/gl_shader_interface.cc
+++ b/source/blender/gpu/opengl/gl_shader_interface.cc
@@ -117,7 +117,28 @@ static inline int image_binding(int32_t program,
switch (type) {
case GL_IMAGE_1D:
case GL_IMAGE_2D:
- case GL_IMAGE_3D: {
+ case GL_IMAGE_3D:
+ case GL_IMAGE_CUBE:
+ case GL_IMAGE_BUFFER:
+ case GL_IMAGE_1D_ARRAY:
+ case GL_IMAGE_2D_ARRAY:
+ case GL_IMAGE_CUBE_MAP_ARRAY:
+ case GL_INT_IMAGE_1D:
+ case GL_INT_IMAGE_2D:
+ case GL_INT_IMAGE_3D:
+ case GL_INT_IMAGE_CUBE:
+ case GL_INT_IMAGE_BUFFER:
+ case GL_INT_IMAGE_1D_ARRAY:
+ case GL_INT_IMAGE_2D_ARRAY:
+ case GL_INT_IMAGE_CUBE_MAP_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_1D:
+ case GL_UNSIGNED_INT_IMAGE_2D:
+ case GL_UNSIGNED_INT_IMAGE_3D:
+ case GL_UNSIGNED_INT_IMAGE_CUBE:
+ case GL_UNSIGNED_INT_IMAGE_BUFFER:
+ case GL_UNSIGNED_INT_IMAGE_1D_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY: {
/* For now just assign a consecutive index. In the future, we should set it in
* the shader using layout(binding = i) and query its value. */
int binding = *image_len;
@@ -298,6 +319,7 @@ GLShaderInterface::GLShaderInterface(GLuint program)
input->binding = input->location = binding;
name_buffer_offset += this->set_input_name(input, name, name_len);
+ enabled_ssbo_mask_ |= (input->binding != -1) ? (1lu << input->binding) : 0lu;
}
/* Builtin Uniforms */
@@ -455,7 +477,7 @@ GLShaderInterface::GLShaderInterface(GLuint program, const shader::ShaderCreateI
if (res.bind_type == ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER) {
copy_input_name(input, res.storagebuf.name, name_buffer_, name_buffer_offset);
input->location = input->binding = res.slot;
- enabled_ubo_mask_ |= (1 << input->binding);
+ enabled_ssbo_mask_ |= (1 << input->binding);
input++;
}
}
diff --git a/source/blender/gpu/opengl/gl_shader_log.cc b/source/blender/gpu/opengl/gl_shader_log.cc
index 174cc63ad81..ec13bc44136 100644
--- a/source/blender/gpu/opengl/gl_shader_log.cc
+++ b/source/blender/gpu/opengl/gl_shader_log.cc
@@ -60,6 +60,15 @@ char *GLLogParser::parse_line(char *log_line, GPULogItem &log_item)
log_item.cursor.row = log_item.cursor.column;
log_item.cursor.column = -1;
}
+ else if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OFFICIAL) &&
+ /* WORKAROUND(@fclem): Both Mesa and AMDGPU-PRO are reported as official. */
+ StringRefNull(GPU_platform_version()).find(" Mesa ") == -1) {
+ /* source:row */
+ log_item.cursor.source = log_item.cursor.row;
+ log_item.cursor.row = log_item.cursor.column;
+ log_item.cursor.column = -1;
+ log_item.source_base_row = true;
+ }
else {
/* line:char */
}
diff --git a/source/blender/gpu/opengl/gl_state.hh b/source/blender/gpu/opengl/gl_state.hh
index 83ff3ffc9e9..5985f1583f2 100644
--- a/source/blender/gpu/opengl/gl_state.hh
+++ b/source/blender/gpu/opengl/gl_state.hh
@@ -124,11 +124,20 @@ static inline GLbitfield to_gl(eGPUBarrier barrier_bits)
if (barrier_bits & GPU_BARRIER_SHADER_IMAGE_ACCESS) {
barrier |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT;
}
+ if (barrier_bits & GPU_BARRIER_SHADER_STORAGE) {
+ barrier |= GL_SHADER_STORAGE_BARRIER_BIT;
+ }
if (barrier_bits & GPU_BARRIER_TEXTURE_FETCH) {
barrier |= GL_TEXTURE_FETCH_BARRIER_BIT;
}
- if (barrier_bits & GPU_BARRIER_SHADER_STORAGE) {
- barrier |= GL_SHADER_STORAGE_BARRIER_BIT;
+ if (barrier_bits & GPU_BARRIER_TEXTURE_UPDATE) {
+ barrier |= GL_TEXTURE_UPDATE_BARRIER_BIT;
+ }
+ if (barrier_bits & GPU_BARRIER_COMMAND) {
+ barrier |= GL_COMMAND_BARRIER_BIT;
+ }
+ if (barrier_bits & GPU_BARRIER_FRAMEBUFFER) {
+ barrier |= GL_FRAMEBUFFER_BARRIER_BIT;
}
if (barrier_bits & GPU_BARRIER_VERTEX_ATTRIB_ARRAY) {
barrier |= GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT;
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc
index 4f5321019d5..87f87e37a7e 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc
@@ -24,6 +24,7 @@
#include "BKE_blender_version.h"
#include "BLI_path_util.h"
+#include "BLI_task.hh"
#include "obj_export_mesh.hh"
#include "obj_export_mtl.hh"
@@ -167,108 +168,85 @@ void OBJWriter::write_object_name(FormatHandler<eFileType::OBJ> &fh,
fh.write<eOBJSyntaxElement::object_name>(object_name);
}
-void OBJWriter::write_vertex_coords(FormatHandler<eFileType::OBJ> &fh,
- const OBJMesh &obj_mesh_data) const
+/* Split up large meshes into multi-threaded jobs; each job processes
+ * this amount of items. */
+static const int chunk_size = 32768;
+static int calc_chunk_count(int count)
{
- const int tot_vertices = obj_mesh_data.tot_vertices();
- for (int i = 0; i < tot_vertices; i++) {
- float3 vertex = obj_mesh_data.calc_vertex_coords(i, export_params_.scaling_factor);
- fh.write<eOBJSyntaxElement::vertex_coords>(vertex[0], vertex[1], vertex[2]);
- }
+ return (count + chunk_size - 1) / chunk_size;
}
-void OBJWriter::write_uv_coords(FormatHandler<eFileType::OBJ> &fh, OBJMesh &r_obj_mesh_data) const
+/* Write /tot_count/ items to OBJ file output. Each item is written
+ * by a /function/ that should be independent from other items.
+ * If the amount of items is large enough (> chunk_size), then writing
+ * will be done in parallel, into temporary FormatHandler buffers that
+ * will be written into the final /fh/ buffer at the end.
+ */
+template<typename Function>
+void obj_parallel_chunked_output(FormatHandler<eFileType::OBJ> &fh,
+ int tot_count,
+ const Function &function)
{
- for (const float2 &uv_vertex : r_obj_mesh_data.get_uv_coords()) {
- fh.write<eOBJSyntaxElement::uv_vertex_coords>(uv_vertex[0], uv_vertex[1]);
+ if (tot_count <= 0) {
+ return;
}
-}
-
-void OBJWriter::write_poly_normals(FormatHandler<eFileType::OBJ> &fh, OBJMesh &obj_mesh_data)
-{
- /* Poly normals should be calculated earlier via store_normal_coords_and_indices. */
- for (const float3 &normal : obj_mesh_data.get_normal_coords()) {
- fh.write<eOBJSyntaxElement::normal>(normal[0], normal[1], normal[2]);
+ /* If we have just one chunk, process it directly into the output
+ * buffer - avoids all the job scheduling and temporary vector allocation
+ * overhead. */
+ const int chunk_count = calc_chunk_count(tot_count);
+ if (chunk_count == 1) {
+ for (int i = 0; i < tot_count; i++) {
+ function(fh, i);
+ }
+ return;
+ }
+ /* Give each chunk its own temporary output buffer, and process them in parallel. */
+ std::vector<FormatHandler<eFileType::OBJ>> buffers(chunk_count);
+ blender::threading::parallel_for(IndexRange(chunk_count), 1, [&](IndexRange range) {
+ for (const int r : range) {
+ int i_start = r * chunk_size;
+ int i_end = std::min(i_start + chunk_size, tot_count);
+ auto &buf = buffers[r];
+ for (int i = i_start; i < i_end; i++) {
+ function(buf, i);
+ }
+ }
+ });
+ /* Emit all temporary output buffers into the destination buffer. */
+ for (auto &buf : buffers) {
+ fh.append_from(buf);
}
}
-int OBJWriter::write_smooth_group(FormatHandler<eFileType::OBJ> &fh,
- const OBJMesh &obj_mesh_data,
- const int poly_index,
- const int last_poly_smooth_group) const
+void OBJWriter::write_vertex_coords(FormatHandler<eFileType::OBJ> &fh,
+ const OBJMesh &obj_mesh_data) const
{
- int current_group = SMOOTH_GROUP_DISABLED;
- if (!export_params_.export_smooth_groups && obj_mesh_data.is_ith_poly_smooth(poly_index)) {
- /* Smooth group calculation is disabled, but polygon is smooth-shaded. */
- current_group = SMOOTH_GROUP_DEFAULT;
- }
- else if (obj_mesh_data.is_ith_poly_smooth(poly_index)) {
- /* Smooth group calc is enabled and polygon is smooth–shaded, so find the group. */
- current_group = obj_mesh_data.ith_smooth_group(poly_index);
- }
-
- if (current_group == last_poly_smooth_group) {
- /* Group has already been written, even if it is "s 0". */
- return current_group;
- }
- fh.write<eOBJSyntaxElement::smooth_group>(current_group);
- return current_group;
+ const int tot_count = obj_mesh_data.tot_vertices();
+ obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler<eFileType::OBJ> &buf, int i) {
+ float3 vertex = obj_mesh_data.calc_vertex_coords(i, export_params_.scaling_factor);
+ buf.write<eOBJSyntaxElement::vertex_coords>(vertex[0], vertex[1], vertex[2]);
+ });
}
-int16_t OBJWriter::write_poly_material(FormatHandler<eFileType::OBJ> &fh,
- const OBJMesh &obj_mesh_data,
- const int poly_index,
- const int16_t last_poly_mat_nr,
- std::function<const char *(int)> matname_fn) const
+void OBJWriter::write_uv_coords(FormatHandler<eFileType::OBJ> &fh, OBJMesh &r_obj_mesh_data) const
{
- if (!export_params_.export_materials || obj_mesh_data.tot_materials() <= 0) {
- return last_poly_mat_nr;
- }
- const int16_t current_mat_nr = obj_mesh_data.ith_poly_matnr(poly_index);
- /* Whenever a polygon with a new material is encountered, write its material
- * and/or group, otherwise pass. */
- if (last_poly_mat_nr == current_mat_nr) {
- return current_mat_nr;
- }
-
- if (current_mat_nr == NOT_FOUND) {
- fh.write<eOBJSyntaxElement::poly_usemtl>(MATERIAL_GROUP_DISABLED);
- return current_mat_nr;
- }
- if (export_params_.export_object_groups) {
- write_object_group(fh, obj_mesh_data);
- }
- const char *mat_name = matname_fn(current_mat_nr);
- if (!mat_name) {
- mat_name = MATERIAL_GROUP_DISABLED;
- }
- fh.write<eOBJSyntaxElement::poly_usemtl>(mat_name);
-
- return current_mat_nr;
+ const Vector<float2> &uv_coords = r_obj_mesh_data.get_uv_coords();
+ const int tot_count = uv_coords.size();
+ obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler<eFileType::OBJ> &buf, int i) {
+ const float2 &uv_vertex = uv_coords[i];
+ buf.write<eOBJSyntaxElement::uv_vertex_coords>(uv_vertex[0], uv_vertex[1]);
+ });
}
-int16_t OBJWriter::write_vertex_group(FormatHandler<eFileType::OBJ> &fh,
- const OBJMesh &obj_mesh_data,
- const int poly_index,
- const int16_t last_poly_vertex_group) const
+void OBJWriter::write_poly_normals(FormatHandler<eFileType::OBJ> &fh, OBJMesh &obj_mesh_data)
{
- if (!export_params_.export_vertex_groups) {
- return last_poly_vertex_group;
- }
- const int16_t current_group = obj_mesh_data.get_poly_deform_group_index(poly_index);
-
- if (current_group == last_poly_vertex_group) {
- /* No vertex group found in this polygon, just like in the last iteration. */
- return current_group;
- }
- if (current_group == NOT_FOUND) {
- fh.write<eOBJSyntaxElement::object_group>(DEFORM_GROUP_DISABLED);
- }
- else {
- fh.write<eOBJSyntaxElement::object_group>(
- obj_mesh_data.get_poly_deform_group_name(current_group));
- }
- return current_group;
+ /* Poly normals should be calculated earlier via store_normal_coords_and_indices. */
+ const Vector<float3> &normal_coords = obj_mesh_data.get_normal_coords();
+ const int tot_count = normal_coords.size();
+ obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler<eFileType::OBJ> &buf, int i) {
+ const float3 &normal = normal_coords[i];
+ buf.write<eOBJSyntaxElement::normal>(normal[0], normal[1], normal[2]);
+ });
}
OBJWriter::func_vert_uv_normal_indices OBJWriter::get_poly_element_writer(
@@ -290,30 +268,78 @@ OBJWriter::func_vert_uv_normal_indices OBJWriter::get_poly_element_writer(
return &OBJWriter::write_vert_indices;
}
+static int get_smooth_group(const OBJMesh &mesh, const OBJExportParams &params, int poly_idx)
+{
+ if (poly_idx < 0) {
+ return NEGATIVE_INIT;
+ }
+ int group = SMOOTH_GROUP_DISABLED;
+ if (mesh.is_ith_poly_smooth(poly_idx)) {
+ group = !params.export_smooth_groups ? SMOOTH_GROUP_DEFAULT : mesh.ith_smooth_group(poly_idx);
+ }
+ return group;
+}
+
void OBJWriter::write_poly_elements(FormatHandler<eFileType::OBJ> &fh,
const IndexOffsets &offsets,
const OBJMesh &obj_mesh_data,
std::function<const char *(int)> matname_fn)
{
- int last_poly_smooth_group = NEGATIVE_INIT;
- int16_t last_poly_vertex_group = NEGATIVE_INIT;
- int16_t last_poly_mat_nr = NEGATIVE_INIT;
-
const func_vert_uv_normal_indices poly_element_writer = get_poly_element_writer(
obj_mesh_data.tot_uv_vertices());
const int tot_polygons = obj_mesh_data.tot_polygons();
- for (int i = 0; i < tot_polygons; i++) {
+ obj_parallel_chunked_output(fh, tot_polygons, [&](FormatHandler<eFileType::OBJ> &buf, int i) {
Vector<int> poly_vertex_indices = obj_mesh_data.calc_poly_vertex_indices(i);
Span<int> poly_uv_indices = obj_mesh_data.calc_poly_uv_indices(i);
Vector<int> poly_normal_indices = obj_mesh_data.calc_poly_normal_indices(i);
- last_poly_smooth_group = write_smooth_group(fh, obj_mesh_data, i, last_poly_smooth_group);
- last_poly_vertex_group = write_vertex_group(fh, obj_mesh_data, i, last_poly_vertex_group);
- last_poly_mat_nr = write_poly_material(fh, obj_mesh_data, i, last_poly_mat_nr, matname_fn);
+ /* Write smoothing group if different from previous. */
+ {
+ const int prev_group = get_smooth_group(obj_mesh_data, export_params_, i - 1);
+ const int group = get_smooth_group(obj_mesh_data, export_params_, i);
+ if (group != prev_group) {
+ buf.write<eOBJSyntaxElement::smooth_group>(group);
+ }
+ }
+
+ /* Write vertex group if different from previous. */
+ if (export_params_.export_vertex_groups) {
+ const int16_t prev_group = i == 0 ? NEGATIVE_INIT :
+ obj_mesh_data.get_poly_deform_group_index(i - 1);
+ const int16_t group = obj_mesh_data.get_poly_deform_group_index(i);
+ if (group != prev_group) {
+ buf.write<eOBJSyntaxElement::object_group>(
+ group == NOT_FOUND ? DEFORM_GROUP_DISABLED :
+ obj_mesh_data.get_poly_deform_group_name(group));
+ }
+ }
+
+ /* Write material name and material group if different from previous. */
+ if (export_params_.export_materials && obj_mesh_data.tot_materials() > 0) {
+ const int16_t prev_mat = i == 0 ? NEGATIVE_INIT : obj_mesh_data.ith_poly_matnr(i - 1);
+ const int16_t mat = obj_mesh_data.ith_poly_matnr(i);
+ if (mat != prev_mat) {
+ if (mat == NOT_FOUND) {
+ buf.write<eOBJSyntaxElement::poly_usemtl>(MATERIAL_GROUP_DISABLED);
+ }
+ else {
+ if (export_params_.export_object_groups) {
+ write_object_group(buf, obj_mesh_data);
+ }
+ const char *mat_name = matname_fn(mat);
+ if (!mat_name) {
+ mat_name = MATERIAL_GROUP_DISABLED;
+ }
+ buf.write<eOBJSyntaxElement::poly_usemtl>(mat_name);
+ }
+ }
+ }
+
+ /* Write polygon elements. */
(this->*poly_element_writer)(
- fh, offsets, poly_vertex_indices, poly_uv_indices, poly_normal_indices);
- }
+ buf, offsets, poly_vertex_indices, poly_uv_indices, poly_normal_indices);
+ });
}
void OBJWriter::write_edges_indices(FormatHandler<eFileType::OBJ> &fh,
@@ -369,11 +395,25 @@ void OBJWriter::write_nurbs_curve(FormatHandler<eFileType::OBJ> &fh,
/**
* In `parm u 0 0.1 ..` line:, (total control points + 2) equidistant numbers in the
- * parameter range are inserted.
+ * parameter range are inserted. However for curves with endpoint flag,
+ * first degree+1 numbers are zeroes, and last degree+1 numbers are ones
*/
+
+ const short flagsu = obj_nurbs_data.get_nurbs_flagu(spline_idx);
+ const bool cyclic = flagsu & CU_NURB_CYCLIC;
+ const bool endpoint = !cyclic && (flagsu & CU_NURB_ENDPOINT);
fh.write<eOBJSyntaxElement::nurbs_parameter_begin>();
for (int i = 1; i <= total_control_points + 2; i++) {
- fh.write<eOBJSyntaxElement::nurbs_parameters>(1.0f * i / (total_control_points + 2 + 1));
+ float parm = 1.0f * i / (total_control_points + 2 + 1);
+ if (endpoint) {
+ if (i <= nurbs_degree) {
+ parm = 0;
+ }
+ else if (i > total_control_points + 2 - nurbs_degree) {
+ parm = 1;
+ }
+ }
+ fh.write<eOBJSyntaxElement::nurbs_parameters>(parm);
}
fh.write<eOBJSyntaxElement::nurbs_parameter_end>();
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh
index 2620d65f28c..c88955e5090 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh
@@ -103,30 +103,6 @@ class OBJWriter : NonMovable, NonCopyable {
*/
void write_poly_normals(FormatHandler<eFileType::OBJ> &fh, OBJMesh &obj_mesh_data);
/**
- * Write smooth group if polygon at the given index is shaded smooth else "s 0"
- */
- int write_smooth_group(FormatHandler<eFileType::OBJ> &fh,
- const OBJMesh &obj_mesh_data,
- int poly_index,
- int last_poly_smooth_group) const;
- /**
- * Write material name and material group of a polygon in the .OBJ file.
- * \return #mat_nr of the polygon at the given index.
- * \note It doesn't write to the material library.
- */
- int16_t write_poly_material(FormatHandler<eFileType::OBJ> &fh,
- const OBJMesh &obj_mesh_data,
- int poly_index,
- int16_t last_poly_mat_nr,
- std::function<const char *(int)> matname_fn) const;
- /**
- * Write the name of the deform group of a polygon.
- */
- int16_t write_vertex_group(FormatHandler<eFileType::OBJ> &fh,
- const OBJMesh &obj_mesh_data,
- int poly_index,
- int16_t last_poly_vertex_group) const;
- /**
* Write polygon elements with at least vertex indices, and conditionally with UV vertex
* indices and polygon normal indices. Also write groups: smooth, vertex, material.
* The matname_fn turns a 0-indexed material slot number in an Object into the
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_io.hh b/source/blender/io/wavefront_obj/exporter/obj_export_io.hh
index 692eb7f5db5..7d8427a8980 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_io.hh
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_io.hh
@@ -177,7 +177,7 @@ constexpr FormattingSyntax syntax_elem_to_formatting(const eOBJSyntaxElement key
return {"curv 0.0 1.0", 0, is_type_string_related<T...>};
}
case eOBJSyntaxElement::nurbs_parameter_begin: {
- return {"parm 0.0", 0, is_type_string_related<T...>};
+ return {"parm u 0.0", 0, is_type_string_related<T...>};
}
case eOBJSyntaxElement::nurbs_parameters: {
return {" %f", 1, is_type_float<T...>};
@@ -313,6 +313,14 @@ class FormatHandler : NonCopyable, NonMovable {
return blocks_.size();
}
+ void append_from(FormatHandler<filetype, buffer_chunk_size, write_local_buffer_size> &v)
+ {
+ blocks_.insert(blocks_.end(),
+ std::make_move_iterator(v.blocks_.begin()),
+ std::make_move_iterator(v.blocks_.end()));
+ v.blocks_.clear();
+ }
+
/**
* Example invocation: `writer->write<eMTLSyntaxElement::newmtl>("foo")`.
*
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc
index 48136dad5f7..3637a3f3c5f 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc
@@ -193,8 +193,8 @@ static void store_bsdf_properties(const nodes::NodeRef *bsdf_node,
copy_property_from_node(SOCK_FLOAT, bnode, "Roughness", {&roughness, 1});
}
/* Empirical approximation. Importer should use the inverse of this method. */
- float spec_exponent = (1.0f - roughness) * 30;
- spec_exponent *= spec_exponent;
+ float spec_exponent = (1.0f - roughness);
+ spec_exponent *= spec_exponent * 1000.0f;
float specular = material->spec;
if (bnode) {
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.cc b/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.cc
index ec690115115..8a6d3b4b93a 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.cc
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.cc
@@ -102,4 +102,10 @@ int OBJCurve::get_nurbs_degree(const int spline_index) const
return nurb->orderu - 1;
}
+short OBJCurve::get_nurbs_flagu(const int spline_index) const
+{
+ const Nurb *const nurb = static_cast<Nurb *>(BLI_findlink(&export_curve_->nurb, spline_index));
+ return nurb->flagu;
+}
+
} // namespace blender::io::obj
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.hh b/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.hh
index 0c71c3cc09d..d831afec0a0 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.hh
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.hh
@@ -61,6 +61,10 @@ class OBJCurve : NonCopyable {
* Get the degree of the NURBS spline at the given index.
*/
int get_nurbs_degree(int spline_index) const;
+ /**
+ * Get the U flags (CU_NURB_*) of the NURBS spline at the given index.
+ */
+ short get_nurbs_flagu(int spline_index) const;
private:
/**
diff --git a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc
index ac2ee8d566b..58329f63650 100644
--- a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc
+++ b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc
@@ -265,7 +265,7 @@ o abcdef
o 012345678901234567890123456789abcd
o 123
curv 0.0 1.0
-parm 0.0
+parm u 0.0
)";
ASSERT_EQ(got_string, expected);
}
@@ -345,8 +345,14 @@ class obj_exporter_regression_test : public obj_exporter_test {
std::string output_mtl_str = read_temp_file_in_string(out_mtl_file_path);
std::string golden_mtl_file_path = blender::tests::flags_test_asset_dir() + "/" + golden_mtl;
std::string golden_mtl_str = read_temp_file_in_string(golden_mtl_file_path);
- ASSERT_TRUE(strings_equal_after_first_lines(output_mtl_str, golden_mtl_str));
- BLI_delete(out_mtl_file_path.c_str(), false, false);
+ are_equal = strings_equal_after_first_lines(output_mtl_str, golden_mtl_str);
+ if (save_failing_test_output && !are_equal) {
+ printf("failing test output in %s\n", out_mtl_file_path.c_str());
+ }
+ ASSERT_TRUE(are_equal);
+ if (!save_failing_test_output || are_equal) {
+ BLI_delete(out_mtl_file_path.c_str(), false, false);
+ }
}
}
};
@@ -410,6 +416,19 @@ TEST_F(obj_exporter_regression_test, nurbs_as_nurbs)
"io_tests/blend_geometry/nurbs.blend", "io_tests/obj/nurbs.obj", "", _export.params);
}
+TEST_F(obj_exporter_regression_test, nurbs_curves_as_nurbs)
+{
+ OBJExportParamsDefault _export;
+ _export.params.forward_axis = OBJ_AXIS_Y_FORWARD;
+ _export.params.up_axis = OBJ_AXIS_Z_UP;
+ _export.params.export_materials = false;
+ _export.params.export_curves_as_nurbs = true;
+ compare_obj_export_to_golden("io_tests/blend_geometry/nurbs_curves.blend",
+ "io_tests/obj/nurbs_curves.obj",
+ "",
+ _export.params);
+}
+
TEST_F(obj_exporter_regression_test, nurbs_as_mesh)
{
OBJExportParamsDefault _export;
diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h
index ddeab9a0759..9c34d78c944 100644
--- a/source/blender/makesdna/DNA_customdata_types.h
+++ b/source/blender/makesdna/DNA_customdata_types.h
@@ -160,9 +160,9 @@ typedef enum CustomDataType {
CD_CUSTOMLOOPNORMAL = 41,
CD_SCULPT_FACE_SETS = 42,
- /* CD_LOCATION = 43, */ /* UNUSED */
- /* CD_RADIUS = 44, */ /* UNUSED */
- /* CD_HAIRCURVE = 45, */ /* UNUSED, can be reused. */
+ /* CD_LOCATION = 43, */ /* UNUSED */
+ /* CD_RADIUS = 44, */ /* UNUSED */
+ CD_PROP_INT8 = 45,
/* CD_HAIRMAPPING = 46, */ /* UNUSED, can be reused. */
CD_PROP_COLOR = 47,
@@ -223,6 +223,7 @@ typedef enum CustomDataType {
#define CD_MASK_PROP_FLOAT3 (1ULL << CD_PROP_FLOAT3)
#define CD_MASK_PROP_FLOAT2 (1ULL << CD_PROP_FLOAT2)
#define CD_MASK_PROP_BOOL (1ULL << CD_PROP_BOOL)
+#define CD_MASK_PROP_INT8 (1ULL << CD_PROP_INT8)
#define CD_MASK_HAIRLENGTH (1ULL << CD_HAIRLENGTH)
@@ -235,7 +236,8 @@ typedef enum CustomDataType {
/* All generic attributes. */
#define CD_MASK_PROP_ALL \
(CD_MASK_PROP_FLOAT | CD_MASK_PROP_FLOAT2 | CD_MASK_PROP_FLOAT3 | CD_MASK_PROP_INT32 | \
- CD_MASK_PROP_COLOR | CD_MASK_PROP_STRING | CD_MASK_MLOOPCOL | CD_MASK_PROP_BOOL)
+ CD_MASK_PROP_COLOR | CD_MASK_PROP_STRING | CD_MASK_MLOOPCOL | CD_MASK_PROP_BOOL | \
+ CD_MASK_PROP_INT8)
typedef struct CustomData_MeshMasks {
uint64_t vmask;
diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h
index b0276d010a4..f2493bd5b85 100644
--- a/source/blender/makesdna/DNA_meshdata_types.h
+++ b/source/blender/makesdna/DNA_meshdata_types.h
@@ -265,6 +265,9 @@ typedef struct MStringProperty {
typedef struct MBoolProperty {
uint8_t b;
} MBoolProperty;
+typedef struct MInt8Property {
+ int8_t i;
+} MInt8Property;
/** \} */
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 2bfd2e71eb7..fd77e8b9f1d 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -514,8 +514,10 @@ typedef struct bNodeTree {
/** Information about how inputs and outputs of the node group interact with fields. */
FieldInferencingInterfaceHandle *field_inferencing_interface;
- /** Set init on fileread. */
- int type, init;
+ int type;
+
+ char _pad1[4];
+
/**
* Sockets in groups have unique identifiers, adding new sockets always
* will increase this counter.
@@ -599,9 +601,6 @@ typedef struct bNodeTree {
#define NTREE_TEXTURE 2
#define NTREE_GEOMETRY 3
-/** #NodeTree.init, flag */
-#define NTREE_TYPE_INIT 1
-
/** #NodeTree.flag */
#define NTREE_DS_EXPAND (1 << 0) /* for animation editors */
#define NTREE_COM_OPENCL (1 << 1) /* use opencl */
diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h
index 5fe67a34dae..70f0dc3f5de 100644
--- a/source/blender/makesdna/DNA_sequence_types.h
+++ b/source/blender/makesdna/DNA_sequence_types.h
@@ -80,6 +80,7 @@ typedef struct StripTransform {
float rotation;
/** 0-1 range, use SEQ_image_transform_origin_offset_pixelspace_get to convert to pixel space. */
float origin[2];
+ int filter;
} StripTransform;
typedef struct StripColorBalance {
@@ -788,6 +789,12 @@ typedef enum SequenceColorTag {
SEQUENCE_COLOR_TOT,
} SequenceColorTag;
+/* Sequence->StripTransform->filter */
+enum {
+ SEQ_TRANSFORM_FILTER_NEAREST = 0,
+ SEQ_TRANSFORM_FILTER_BILINEAR = 1,
+};
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 130402a31db..43439428ea7 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -104,6 +104,8 @@ extern StructRNA RNA_BuildGpencilModifier;
extern StructRNA RNA_BuildModifier;
extern StructRNA RNA_ByteColorAttribute;
extern StructRNA RNA_ByteColorAttributeValue;
+extern StructRNA RNA_ByteIntAttribute;
+extern StructRNA RNA_ByteIntAttributeValue;
extern StructRNA RNA_CacheFile;
extern StructRNA RNA_CacheFileLayer;
extern StructRNA RNA_Camera;
diff --git a/source/blender/makesrna/intern/rna_attribute.c b/source/blender/makesrna/intern/rna_attribute.c
index 35da353a043..da835fb89c4 100644
--- a/source/blender/makesrna/intern/rna_attribute.c
+++ b/source/blender/makesrna/intern/rna_attribute.c
@@ -46,6 +46,7 @@ const EnumPropertyItem rna_enum_attribute_type_items[] = {
{CD_PROP_STRING, "STRING", 0, "String", "Text string"},
{CD_PROP_BOOL, "BOOLEAN", 0, "Boolean", "True or false"},
{CD_PROP_FLOAT2, "FLOAT2", 0, "2D Vector", "2D vector with floating-point values"},
+ {CD_PROP_INT8, "INT8", 0, "8-Bit Integer", "Smaller integer with a range from -128 to 127"},
{0, NULL, 0, NULL, NULL},
};
@@ -59,6 +60,7 @@ const EnumPropertyItem rna_enum_attribute_type_with_auto_items[] = {
{CD_PROP_STRING, "STRING", 0, "String", "Text string"},
{CD_PROP_BOOL, "BOOLEAN", 0, "Boolean", "True or false"},
{CD_PROP_FLOAT2, "FLOAT2", 0, "2D Vector", "2D vector with floating-point values"},
+ {CD_PROP_INT8, "INT8", 0, "8-Bit Integer", "Smaller integer with a range from -128 to 127"},
{0, NULL, 0, NULL, NULL},
};
@@ -133,6 +135,8 @@ static StructRNA *srna_by_custom_data_layer_type(const CustomDataType type)
return &RNA_BoolAttribute;
case CD_PROP_FLOAT2:
return &RNA_Float2Attribute;
+ case CD_PROP_INT8:
+ return &RNA_ByteIntAttribute;
default:
return NULL;
}
@@ -253,6 +257,9 @@ static void rna_Attribute_data_begin(CollectionPropertyIterator *iter, PointerRN
case CD_PROP_FLOAT2:
struct_size = sizeof(float[2]);
break;
+ case CD_PROP_INT8:
+ struct_size = sizeof(int8_t);
+ break;
default:
struct_size = 0;
length = 0;
@@ -294,6 +301,28 @@ static void rna_ByteColorAttributeValue_color_set(PointerRNA *ptr, const float *
linearrgb_to_srgb_uchar4(&mlcol->r, values);
}
+/* Int8 Attribute. */
+
+static int rna_ByteIntAttributeValue_get(PointerRNA *ptr)
+{
+ int8_t *value = (int8_t *)ptr->data;
+ return (int)(*value);
+}
+
+static void rna_ByteIntAttributeValue_set(PointerRNA *ptr, const int new_value)
+{
+ int8_t *value = (int8_t *)ptr->data;
+ if (new_value > INT8_MAX) {
+ *value = INT8_MAX;
+ }
+ else if (new_value < INT8_MIN) {
+ *value = INT8_MIN;
+ }
+ else {
+ *value = (int8_t)new_value;
+ }
+}
+
/* Attribute Group */
static PointerRNA rna_AttributeGroup_new(
@@ -648,6 +677,36 @@ static void rna_def_attribute_bool(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "b", 0x01);
}
+static void rna_def_attribute_int8(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "ByteIntAttribute", "Attribute");
+ RNA_def_struct_sdna(srna, "CustomDataLayer");
+ RNA_def_struct_ui_text(srna, "8-bit Int Attribute", "8-bit int geometry attribute");
+
+ prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_struct_type(prop, "ByteIntAttributeValue");
+ RNA_def_property_collection_funcs(prop,
+ "rna_Attribute_data_begin",
+ "rna_iterator_array_next",
+ "rna_iterator_array_end",
+ "rna_iterator_array_get",
+ "rna_Attribute_data_length",
+ NULL,
+ NULL,
+ NULL);
+
+ srna = RNA_def_struct(brna, "ByteIntAttributeValue", NULL);
+ RNA_def_struct_sdna(srna, "MInt8Property");
+ RNA_def_struct_ui_text(
+ srna, "8-bit Integer Attribute Value", "8-bit value in geometry attribute");
+ prop = RNA_def_property(srna, "value", PROP_INT, PROP_NONE);
+ RNA_def_property_int_funcs(
+ prop, "rna_ByteIntAttributeValue_get", "rna_ByteIntAttributeValue_set", NULL);
+}
+
static void rna_def_attribute_float2(BlenderRNA *brna)
{
StructRNA *srna;
@@ -723,6 +782,7 @@ static void rna_def_attribute(BlenderRNA *brna)
rna_def_attribute_string(brna);
rna_def_attribute_bool(brna);
rna_def_attribute_float2(brna);
+ rna_def_attribute_int8(brna);
}
/* Mesh/PointCloud/Hair.attributes */
diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c
index 6c3e3ab3058..9fee54ef38d 100644
--- a/source/blender/makesrna/intern/rna_sequencer.c
+++ b/source/blender/makesrna/intern/rna_sequencer.c
@@ -1456,6 +1456,12 @@ static void rna_def_strip_crop(BlenderRNA *brna)
RNA_def_struct_path_func(srna, "rna_SequenceCrop_path");
}
+static const EnumPropertyItem transform_filter_items[] = {
+ {SEQ_TRANSFORM_FILTER_NEAREST, "NEAREST", 0, "Nearest", ""},
+ {SEQ_TRANSFORM_FILTER_BILINEAR, "BILINEAR", 0, "Bilinear", ""},
+ {0, NULL, 0, NULL, NULL},
+};
+
static void rna_def_strip_transform(BlenderRNA *brna)
{
StructRNA *srna;
@@ -1502,6 +1508,13 @@ static void rna_def_strip_transform(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0, 1, 1, 3);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceTransform_update");
+ prop = RNA_def_property(srna, "filter", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "filter");
+ RNA_def_property_enum_items(prop, transform_filter_items);
+ RNA_def_property_enum_default(prop, SEQ_TRANSFORM_FILTER_BILINEAR);
+ RNA_def_property_ui_text(prop, "Filter", "Type of filter to use for image transformation");
+ RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceTransform_update");
+
RNA_def_struct_path_func(srna, "rna_SequenceTransform_path");
}
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index e2411f5f4ae..9a3c40bf306 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -4308,7 +4308,7 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna)
prop = RNA_def_property(srna, "bone_wire_alpha", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "overlay.bone_wire_alpha");
RNA_def_property_ui_text(
- prop, "Bone Wireframe Opacity", "Maximim opacity of bones in wireframe display mode");
+ prop, "Bone Wireframe Opacity", "Maximum opacity of bones in wireframe display mode");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 1, 2);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
diff --git a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc
index 5362d86a87f..f59af9074ce 100644
--- a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc
+++ b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc
@@ -1347,7 +1347,7 @@ class GeometryNodesEvaluator {
}
input_state.usage = ValueUsage::Unused;
- /* If the input is unused, it's value can be destructed now. */
+ /* If the input is unused, its value can be destructed now. */
this->destruct_input_value_if_exists(locked_node, socket);
if (input_state.was_ready_for_execution) {
diff --git a/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc b/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc
index deb149fd0f0..3c790079b5b 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc
@@ -26,7 +26,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Geometry>(N_("Geometry"))
.supported_type({GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_MESH});
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
- b.add_input<decl::Float>(N_("Distance")).default_value(0.1f).min(0.0f).subtype(PROP_DISTANCE);
+ b.add_input<decl::Float>(N_("Distance")).default_value(0.001f).min(0.0f).subtype(PROP_DISTANCE);
b.add_output<decl::Geometry>(N_("Geometry"));
}
diff --git a/source/blender/render/intern/bake.c b/source/blender/render/intern/bake.c
index 93d2f721cc5..883e026472b 100644
--- a/source/blender/render/intern/bake.c
+++ b/source/blender/render/intern/bake.c
@@ -512,9 +512,9 @@ static TriTessFace *mesh_calc_tri_tessface(Mesh *me, bool tangent, Mesh *me_eval
triangles[i].mverts[0] = &mvert[me->mloop[lt->tri[0]].v];
triangles[i].mverts[1] = &mvert[me->mloop[lt->tri[1]].v];
triangles[i].mverts[2] = &mvert[me->mloop[lt->tri[2]].v];
- triangles[i].vert_normals[0] = &vert_normals[me->mloop[lt->tri[0]].v][0];
- triangles[i].vert_normals[1] = &vert_normals[me->mloop[lt->tri[1]].v][1];
- triangles[i].vert_normals[2] = &vert_normals[me->mloop[lt->tri[2]].v][2];
+ triangles[i].vert_normals[0] = vert_normals[me->mloop[lt->tri[0]].v];
+ triangles[i].vert_normals[1] = vert_normals[me->mloop[lt->tri[1]].v];
+ triangles[i].vert_normals[2] = vert_normals[me->mloop[lt->tri[2]].v];
triangles[i].is_smooth = (mp->flag & ME_SMOOTH) != 0;
if (tangent) {
diff --git a/source/blender/render/intern/texture_margin.cc b/source/blender/render/intern/texture_margin.cc
index b864aa64709..7aff01242e3 100644
--- a/source/blender/render/intern/texture_margin.cc
+++ b/source/blender/render/intern/texture_margin.cc
@@ -123,7 +123,7 @@ class TextureMarginMap {
void rasterize_tri(float *v1, float *v2, float *v3, uint32_t value, char *mask)
{
/* NOTE: This is not thread safe, because the value to be written by the rasterizer is
- * a class member. If this is ever made multi-threaded each thread needs to get it's own. */
+ * a class member. If this is ever made multi-threaded each thread needs to get its own. */
value_to_store_ = value;
mask_ = mask;
zspan_scanconvert(
@@ -376,7 +376,7 @@ class TextureMarginMap {
}
/**
- * Find which edge of the src_poly is closest to x,y. Look up it's adjacent UV-edge and polygon.
+ * Find which edge of the src_poly is closest to x,y. Look up its adjacent UV-edge and polygon.
* Then return the location of the equivalent pixel in the other polygon.
* Returns true if a new pixel location was found, false if it wasn't, which can happen if the
* margin pixel is on a corner, or the UV-edge doesn't have an adjacent polygon.
@@ -470,7 +470,7 @@ class TextureMarginMap {
float2 other_edgepoint1 = uv_to_xy(mloopuv_[other_edge]);
float2 other_edgepoint2 = uv_to_xy(mloopuv_[other_edge2]);
- /* Calculate the vector from the order edges last point to it's first point. */
+ /* Calculate the vector from the order edges last point to its first point. */
float2 other_ab = other_edgepoint1 - other_edgepoint2;
float2 other_reflect_point = other_edgepoint2 + (found_t * other_ab);
float2 perpendicular_other_ab;
diff --git a/source/blender/sequencer/intern/render.c b/source/blender/sequencer/intern/render.c
index 482425e70d3..a6c627e5ce7 100644
--- a/source/blender/sequencer/intern/render.c
+++ b/source/blender/sequencer/intern/render.c
@@ -524,8 +524,15 @@ static void sequencer_preprocess_transform_crop(
const float crop_scale_factor = do_scale_to_render_size ? preview_scale_factor : 1.0f;
sequencer_image_crop_init(seq, in, crop_scale_factor, &source_crop);
- const eIMBInterpolationFilterMode filter = context->for_render ? IMB_FILTER_BILINEAR :
- IMB_FILTER_NEAREST;
+ eIMBInterpolationFilterMode filter;
+ const StripTransform *transform = seq->strip->transform;
+ if (transform->filter == SEQ_TRANSFORM_FILTER_NEAREST) {
+ filter = IMB_FILTER_NEAREST;
+ }
+ else {
+ filter = IMB_FILTER_BILINEAR;
+ }
+
IMB_transform(in, out, IMB_TRANSFORM_MODE_CROP_SRC, filter, transform_matrix, &source_crop);
if (!seq_image_transform_transparency_gained(context, seq)) {
diff --git a/source/blender/sequencer/intern/sequencer.c b/source/blender/sequencer/intern/sequencer.c
index 1c7fe927381..8e824f59dda 100644
--- a/source/blender/sequencer/intern/sequencer.c
+++ b/source/blender/sequencer/intern/sequencer.c
@@ -85,6 +85,7 @@ static Strip *seq_strip_alloc(int type)
strip->transform->scale_y = 1;
strip->transform->origin[0] = 0.5f;
strip->transform->origin[1] = 0.5f;
+ strip->transform->filter = SEQ_TRANSFORM_FILTER_BILINEAR;
strip->crop = MEM_callocN(sizeof(struct StripCrop), "StripCrop");
}