Changeset View
Standalone View
source/blender/draw/intern/draw_cache_impl_curves.cc
| Show All 17 Lines | |||||||||||||||
| #include "BLI_span.hh" | #include "BLI_span.hh" | ||||||||||||||
| #include "BLI_task.hh" | #include "BLI_task.hh" | ||||||||||||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||||||||||||
| #include "DNA_curves_types.h" | #include "DNA_curves_types.h" | ||||||||||||||
| #include "DNA_object_types.h" | #include "DNA_object_types.h" | ||||||||||||||
| #include "DNA_scene_types.h" | #include "DNA_scene_types.h" | ||||||||||||||
| #include "DEG_depsgraph_query.h" | |||||||||||||||
| #include "BKE_curves.hh" | #include "BKE_curves.hh" | ||||||||||||||
| #include "BKE_geometry_set.hh" | #include "BKE_geometry_set.hh" | ||||||||||||||
| #include "GPU_batch.h" | #include "GPU_batch.h" | ||||||||||||||
| #include "GPU_material.h" | #include "GPU_material.h" | ||||||||||||||
| #include "GPU_texture.h" | #include "GPU_texture.h" | ||||||||||||||
| #include "DRW_render.h" | #include "DRW_render.h" | ||||||||||||||
| ▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | static void curves_discard_attributes(CurvesEvalCache &curves_cache) | ||||||||||||||
| } | } | ||||||||||||||
| } | } | ||||||||||||||
| static void curves_batch_cache_clear_data(CurvesEvalCache &curves_cache) | static void curves_batch_cache_clear_data(CurvesEvalCache &curves_cache) | ||||||||||||||
| { | { | ||||||||||||||
| /* TODO: more granular update tagging. */ | /* TODO: more granular update tagging. */ | ||||||||||||||
| GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_point_buf); | GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_point_buf); | ||||||||||||||
| GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_length_buf); | GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_length_buf); | ||||||||||||||
| GPU_VERTBUF_DISCARD_SAFE(curves_cache.data_edit_points); | GPU_VERTBUF_DISCARD_SAFE(curves_cache.edit_points_pos); | ||||||||||||||
| GPU_VERTBUF_DISCARD_SAFE(curves_cache.edit_points_flags); | |||||||||||||||
| GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_strand_buf); | GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_strand_buf); | ||||||||||||||
| GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_strand_seg_buf); | GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_strand_seg_buf); | ||||||||||||||
| for (const int i : IndexRange(MAX_HAIR_SUBDIV)) { | for (const int i : IndexRange(MAX_HAIR_SUBDIV)) { | ||||||||||||||
| GPU_VERTBUF_DISCARD_SAFE(curves_cache.final[i].proc_buf); | GPU_VERTBUF_DISCARD_SAFE(curves_cache.final[i].proc_buf); | ||||||||||||||
| for (const int j : IndexRange(MAX_THICKRES)) { | for (const int j : IndexRange(MAX_THICKRES)) { | ||||||||||||||
| GPU_BATCH_DISCARD_SAFE(curves_cache.final[i].proc_hairs[j]); | GPU_BATCH_DISCARD_SAFE(curves_cache.final[i].proc_hairs[j]); | ||||||||||||||
| ▲ Show 20 Lines • Show All 137 Lines • ▼ Show 20 Lines | |||||||||||||||
| static void curves_batch_cache_ensure_procedural_pos(const Curves &curves, | static void curves_batch_cache_ensure_procedural_pos(const Curves &curves, | ||||||||||||||
| CurvesEvalCache &cache, | CurvesEvalCache &cache, | ||||||||||||||
| GPUMaterial *UNUSED(gpu_material)) | GPUMaterial *UNUSED(gpu_material)) | ||||||||||||||
| { | { | ||||||||||||||
| if (cache.proc_point_buf == nullptr || DRW_vbo_requested(cache.proc_point_buf)) { | if (cache.proc_point_buf == nullptr || DRW_vbo_requested(cache.proc_point_buf)) { | ||||||||||||||
| /* Initialize vertex format. */ | /* Initialize vertex format. */ | ||||||||||||||
| GPUVertFormat format = {0}; | GPUVertFormat format = {0}; | ||||||||||||||
| GPU_vertformat_attr_add(&format, "posTime", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); | GPU_vertformat_attr_add(&format, "posTime", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); | ||||||||||||||
| GPU_vertformat_alias_add(&format, "pos"); | |||||||||||||||
| cache.proc_point_buf = GPU_vertbuf_create_with_format_ex( | cache.proc_point_buf = GPU_vertbuf_create_with_format_ex( | ||||||||||||||
| &format, GPU_USAGE_STATIC | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY); | &format, GPU_USAGE_STATIC | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY); | ||||||||||||||
| GPU_vertbuf_data_alloc(cache.proc_point_buf, cache.point_len); | GPU_vertbuf_data_alloc(cache.proc_point_buf, cache.point_len); | ||||||||||||||
| MutableSpan posTime_data{ | MutableSpan posTime_data{ | ||||||||||||||
| static_cast<PositionAndParameter *>(GPU_vertbuf_get_data(cache.proc_point_buf)), | static_cast<PositionAndParameter *>(GPU_vertbuf_get_data(cache.proc_point_buf)), | ||||||||||||||
| cache.point_len}; | cache.point_len}; | ||||||||||||||
| GPUVertFormat length_format = {0}; | GPUVertFormat length_format = {0}; | ||||||||||||||
| GPU_vertformat_attr_add(&length_format, "hairLength", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); | GPU_vertformat_attr_add(&length_format, "hairLength", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); | ||||||||||||||
| cache.proc_length_buf = GPU_vertbuf_create_with_format_ex( | cache.proc_length_buf = GPU_vertbuf_create_with_format_ex( | ||||||||||||||
| &length_format, GPU_USAGE_STATIC | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY); | &length_format, GPU_USAGE_STATIC | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY); | ||||||||||||||
| GPU_vertbuf_data_alloc(cache.proc_length_buf, cache.strands_len); | GPU_vertbuf_data_alloc(cache.proc_length_buf, cache.strands_len); | ||||||||||||||
| MutableSpan hairLength_data{static_cast<float *>(GPU_vertbuf_get_data(cache.proc_length_buf)), | MutableSpan hairLength_data{static_cast<float *>(GPU_vertbuf_get_data(cache.proc_length_buf)), | ||||||||||||||
| cache.strands_len}; | cache.strands_len}; | ||||||||||||||
| curves_batch_cache_fill_segments_proc_pos(curves, posTime_data, hairLength_data); | curves_batch_cache_fill_segments_proc_pos(curves, posTime_data, hairLength_data); | ||||||||||||||
| } | } | ||||||||||||||
| } | } | ||||||||||||||
| static void curves_batch_cache_ensure_data_edit_points(const Curves &curves_id, | static void curves_batch_cache_ensure_edit_points_pos(const Curves &curves_id, | ||||||||||||||
| CurvesEvalCache &cache) | |||||||||||||||
HooglyBoogly: clang format | |||||||||||||||
| { | |||||||||||||||
| using namespace blender; | |||||||||||||||
| const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); | |||||||||||||||
| static GPUVertFormat format_pos = {0}; | |||||||||||||||
| static uint pos; | |||||||||||||||
| if (format_pos.attr_len == 0) { | |||||||||||||||
| pos = GPU_vertformat_attr_add(&format_pos, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); | |||||||||||||||
| } | |||||||||||||||
| GPU_vertbuf_init_with_format(cache.edit_points_pos, &format_pos); | |||||||||||||||
| GPU_vertbuf_data_alloc(cache.edit_points_pos, curves.points_num()); | |||||||||||||||
Not Done Inline Actions
A simple copy is more obvious here and should be faster. HooglyBoogly: A simple copy is more obvious here and should be faster. | |||||||||||||||
| Span<float3> positions = curves.positions(); | |||||||||||||||
| for (const int point_i : positions.index_range()) { | |||||||||||||||
| GPU_vertbuf_attr_set(cache.edit_points_pos, pos, point_i, positions[point_i]); | |||||||||||||||
| } | |||||||||||||||
| } | |||||||||||||||
| static void curves_batch_cache_ensure_edit_points_flags(const Curves &curves_id, | |||||||||||||||
| CurvesEvalCache &cache) | CurvesEvalCache &cache) | ||||||||||||||
| { | { | ||||||||||||||
| using namespace blender; | using namespace blender; | ||||||||||||||
| const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); | const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); | ||||||||||||||
| static GPUVertFormat format_data = {0}; | static GPUVertFormat format_data = {0}; | ||||||||||||||
| static uint data; | static uint data; | ||||||||||||||
| if (format_data.attr_len == 0) { | if (format_data.attr_len == 0) { | ||||||||||||||
| data = GPU_vertformat_attr_add(&format_data, "data", GPU_COMP_U8, 1, GPU_FETCH_INT); | data = GPU_vertformat_attr_add(&format_data, "data", GPU_COMP_U8, 1, GPU_FETCH_INT); | ||||||||||||||
| } | } | ||||||||||||||
| GPU_vertbuf_init_with_format(cache.data_edit_points, &format_data); | GPU_vertbuf_init_with_format(cache.edit_points_flags, &format_data); | ||||||||||||||
| GPU_vertbuf_data_alloc(cache.data_edit_points, curves.points_num()); | GPU_vertbuf_data_alloc(cache.edit_points_flags, curves.points_num()); | ||||||||||||||
| VArray<float> selection; | VArray<float> selection; | ||||||||||||||
| switch (curves_id.selection_domain) { | switch (curves_id.selection_domain) { | ||||||||||||||
| case ATTR_DOMAIN_POINT: | case ATTR_DOMAIN_POINT: | ||||||||||||||
| selection = curves.selection_point_float(); | selection = curves.selection_point_float(); | ||||||||||||||
| for (const int point_i : selection.index_range()) { | for (const int point_i : selection.index_range()) { | ||||||||||||||
Not Done Inline ActionsI'd expect GPU_vertbuf_attr_fill to work fine here. Faster and simpler than setting the data per-element in a loop. HooglyBoogly: I'd expect `GPU_vertbuf_attr_fill` to work fine here. Faster and simpler than setting the data… | |||||||||||||||
| uint8_t vflag = 0; | uint8_t vflag = 0; | ||||||||||||||
Not Done Inline ActionsThese aren't really flags anymore are they? HooglyBoogly: These aren't really flags anymore are they?
Do we really have to upload a float for every point… | |||||||||||||||
Done Inline ActionsWill rename that function. Regarding the float: it is not deal, but the patch is now reusing the old particle line/point shaders (and these used a float to be able to show the weight gradient on the lines). We could get it back to just a flag, just dont think there is an existing shader that is capable of both selection and segment highlighting -- we would have to add one I think. lichtwerk: Will rename that function.
Regarding the float: it is not deal, but the patch is now reusing… | |||||||||||||||
Not Done Inline ActionsOkay, that will be much easier to change when the particle system is gone then. It's probably not worth adding a new shader right now. HooglyBoogly: Okay, that will be much easier to change when the particle system is gone then. It's probably… | |||||||||||||||
| const float point_selection = selection[point_i]; | const float point_selection = selection[point_i]; | ||||||||||||||
| SET_FLAG_FROM_TEST(vflag, (point_selection > 0.0f), VFLAG_VERT_SELECTED); | SET_FLAG_FROM_TEST(vflag, (point_selection > 0.0f), VFLAG_VERT_SELECTED); | ||||||||||||||
| GPU_vertbuf_attr_set(cache.data_edit_points, data, point_i, &vflag); | GPU_vertbuf_attr_set(cache.edit_points_flags, data, point_i, &vflag); | ||||||||||||||
| } | } | ||||||||||||||
| break; | break; | ||||||||||||||
| case ATTR_DOMAIN_CURVE: | case ATTR_DOMAIN_CURVE: | ||||||||||||||
| selection = curves.selection_curve_float(); | selection = curves.selection_curve_float(); | ||||||||||||||
| for (const int curve_i : curves.curves_range()) { | for (const int curve_i : curves.curves_range()) { | ||||||||||||||
| uint8_t vflag = 0; | uint8_t vflag = 0; | ||||||||||||||
| const float curve_selection = selection[curve_i]; | const float curve_selection = selection[curve_i]; | ||||||||||||||
| SET_FLAG_FROM_TEST(vflag, (curve_selection > 0.0f), VFLAG_VERT_SELECTED); | SET_FLAG_FROM_TEST(vflag, (curve_selection > 0.0f), VFLAG_VERT_SELECTED); | ||||||||||||||
| const IndexRange points = curves.points_for_curve(curve_i); | const IndexRange points = curves.points_for_curve(curve_i); | ||||||||||||||
| for (const int point_i : points) { | for (const int point_i : points) { | ||||||||||||||
| GPU_vertbuf_attr_set(cache.data_edit_points, data, point_i, &vflag); | GPU_vertbuf_attr_set(cache.edit_points_flags, data, point_i, &vflag); | ||||||||||||||
| } | } | ||||||||||||||
| } | } | ||||||||||||||
| break; | break; | ||||||||||||||
| } | } | ||||||||||||||
| } | } | ||||||||||||||
| void drw_curves_get_attribute_sampler_name(const char *layer_name, char r_sampler_name[32]) | void drw_curves_get_attribute_sampler_name(const char *layer_name, char r_sampler_name[32]) | ||||||||||||||
| { | { | ||||||||||||||
| ▲ Show 20 Lines • Show All 351 Lines • ▼ Show 20 Lines | default: | ||||||||||||||
| BLI_assert_unreachable(); | BLI_assert_unreachable(); | ||||||||||||||
| return nullptr; | return nullptr; | ||||||||||||||
| } | } | ||||||||||||||
| } | } | ||||||||||||||
| void DRW_curves_batch_cache_create_requested(Object *ob) | void DRW_curves_batch_cache_create_requested(Object *ob) | ||||||||||||||
| { | { | ||||||||||||||
| Curves *curves = static_cast<Curves *>(ob->data); | Curves *curves = static_cast<Curves *>(ob->data); | ||||||||||||||
| Object *orig = DEG_get_original_object(ob); | |||||||||||||||
Not Done Inline ActionsWould DEG_get_original_id(curves) make more sense, since it's the original curves data-block we're drawing? HooglyBoogly: Would `DEG_get_original_id(curves)` make more sense, since it's the original curves data-block… | |||||||||||||||
Not Done Inline ActionsHm, the object ID has an orig_id and is LIB_TAG_COPIED_ON_WRITE whereas the curves ID does not have an orig_id and is not LIB_TAG_COPIED_ON_WRITE Bit on shaky ground, will dig deeper... So, no, until further notice this would not work... lichtwerk: Hm, the object ID has an `orig_id` and is `LIB_TAG_COPIED_ON_WRITE` whereas the curves ID does… | |||||||||||||||
Done Inline ActionsOh, I think this might make sense. The evaluated curves might be totally new (e.g. created from geometry nodes), so it won't have the "orig ID" pointer. But the object should, at least in most cases. So just ignore this comment :) HooglyBoogly: Oh, I think this might make sense. The evaluated curves might be totally new (e.g. created from… | |||||||||||||||
| Curves *curves_orig = static_cast<Curves *>(orig->data); | |||||||||||||||
| CurvesBatchCache &cache = curves_batch_cache_get(*curves); | CurvesBatchCache &cache = curves_batch_cache_get(*curves); | ||||||||||||||
| if (DRW_batch_requested(cache.edit_points, GPU_PRIM_POINTS)) { | if (DRW_batch_requested(cache.edit_points, GPU_PRIM_POINTS)) { | ||||||||||||||
| DRW_vbo_request(cache.edit_points, &cache.curves_cache.proc_point_buf); | DRW_vbo_request(cache.edit_points, &cache.curves_cache.edit_points_pos); | ||||||||||||||
| DRW_vbo_request(cache.edit_points, &cache.curves_cache.data_edit_points); | DRW_vbo_request(cache.edit_points, &cache.curves_cache.edit_points_flags); | ||||||||||||||
| } | } | ||||||||||||||
| if (DRW_vbo_requested(cache.curves_cache.edit_points_pos)) { | |||||||||||||||
| if (DRW_vbo_requested(cache.curves_cache.proc_point_buf)) { | curves_batch_cache_ensure_edit_points_pos(*curves_orig, cache.curves_cache); | ||||||||||||||
| curves_batch_cache_ensure_procedural_pos(*curves, cache.curves_cache, nullptr); | |||||||||||||||
| } | } | ||||||||||||||
| if (DRW_vbo_requested(cache.curves_cache.edit_points_flags)) { | |||||||||||||||
| if (DRW_vbo_requested(cache.curves_cache.data_edit_points)) { | curves_batch_cache_ensure_edit_points_flags(*curves_orig, cache.curves_cache); | ||||||||||||||
| curves_batch_cache_ensure_data_edit_points(*curves, cache.curves_cache); | |||||||||||||||
| } | } | ||||||||||||||
| } | } | ||||||||||||||
clang format