diff options
author | Falk David <falkdavid@gmx.de> | 2022-02-07 14:13:22 +0300 |
---|---|---|
committer | Falk David <falkdavid@gmx.de> | 2022-02-07 14:13:22 +0300 |
commit | c3ac35d6e73ded3a45b392336c337abaf6b64a13 (patch) | |
tree | f81727fdce68da25db741120818ea49a93c7b7cd /source/blender | |
parent | a59861518262b19c8d5f352429c96c304e349638 (diff) | |
parent | 463828a7a840b7ae38b2b62637826b71d14b5a80 (diff) |
Merge branch 'patch/gpencil-update-on-write' into patch/gpencil-undo-system
Diffstat (limited to 'source/blender')
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 ¶ms, 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"); } |