WIP: Vulkan: Clearing Storage Buffers #105299

Closed
Jeroen Bakker wants to merge 73 commits from Jeroen-Bakker:gpu-storage-buffer-clear into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
15 changed files with 226 additions and 43 deletions
Showing only changes of commit 17157843cd - Show all commits

View File

@ -1,9 +1,9 @@
name: Bug Report
about: File a bug report
labels:
- "type::Report"
- "status::Needs Triage"
- "priority::Normal"
- "Type/Report"
- "Status/Needs Triage"
- "Priority/Normal"
body:
- type: markdown
attributes:

View File

@ -1,7 +1,7 @@
name: Design
about: Create a design task (for developers only)
labels:
- "type::Design"
- "Type/Design"
body:
- type: textarea
id: body

View File

@ -1,7 +1,7 @@
name: To Do
about: Create a to do task (for developers only)
labels:
- "type::To Do"
- "Type/To Do"
body:
- type: textarea
id: body

View File

@ -225,11 +225,15 @@ MetalDevice::MetalDevice(const DeviceInfo &info, Stats &stats, Profiler &profile
mtlAncillaryArgEncoder = [mtlDevice newArgumentEncoderWithArguments:ancillary_desc];
// preparing the blas arg encoder
MTLArgumentDescriptor *arg_desc_blas = [[MTLArgumentDescriptor alloc] init];
arg_desc_blas.dataType = MTLDataTypeInstanceAccelerationStructure;
arg_desc_blas.access = MTLArgumentAccessReadOnly;
mtlBlasArgEncoder = [mtlDevice newArgumentEncoderWithArguments:@[ arg_desc_blas ]];
[arg_desc_blas release];
if (@available(macos 11.0, *)) {
if (use_metalrt) {
MTLArgumentDescriptor *arg_desc_blas = [[MTLArgumentDescriptor alloc] init];
arg_desc_blas.dataType = MTLDataTypeInstanceAccelerationStructure;
arg_desc_blas.access = MTLArgumentAccessReadOnly;
mtlBlasArgEncoder = [mtlDevice newArgumentEncoderWithArguments:@[ arg_desc_blas ]];
[arg_desc_blas release];
}
}
for (int i = 0; i < ancillary_desc.count; i++) {
[ancillary_desc[i] release];

View File

@ -215,6 +215,10 @@ std::string AssetLibraryService::root_path_from_library_ref(
return "";
}
if (ELEM(library_reference.type, ASSET_LIBRARY_ESSENTIALS)) {
return essentials_directory_path();
}
bUserAssetLibrary *custom_library = find_custom_asset_library_from_library_ref(
library_reference);
if (!custom_library || !custom_library->path[0]) {

View File

@ -263,6 +263,8 @@ static void brush_blend_write(BlendWriter *writer, ID *id, const void *id_addres
if (brush->gradient) {
BLO_write_struct(writer, ColorBand, brush->gradient);
}
BKE_previewimg_blend_write(writer, brush->preview);
}
static void brush_blend_read_data(BlendDataReader *reader, ID *id)
@ -348,7 +350,9 @@ static void brush_blend_read_data(BlendDataReader *reader, ID *id)
}
}
brush->preview = nullptr;
BLO_read_data_address(reader, &brush->preview);
BKE_previewimg_blend_read(reader, brush->preview);
brush->icon_imbuf = nullptr;
}

View File

@ -3,7 +3,36 @@
#include "BKE_curves.hh"
#include "BKE_geometry_fields.hh"
#include "BLI_task.hh"
#include "DNA_object_types.h"
#include "ED_curves.h"
#include "ED_transverts.h"
namespace blender::ed::curves {
void transverts_from_curves_positions_create(bke::CurvesGeometry &curves, TransVertStore *tvs)
{
Vector<int64_t> selected_indices;
IndexMask selection = retrieve_selected_points(curves, selected_indices);
MutableSpan<float3> positions = curves.positions_for_write();
tvs->transverts = static_cast<TransVert *>(
MEM_calloc_arrayN(selection.size(), sizeof(TransVert), __func__));
tvs->transverts_tot = selection.size();
threading::parallel_for(selection.index_range(), 1024, [&](const IndexRange selection_range) {
for (const int point_i : selection_range) {
TransVert &tv = tvs->transverts[point_i];
tv.loc = positions[selection[point_i]];
tv.flag = SELECT;
copy_v3_v3(tv.oldloc, tv.loc);
}
});
}
} // namespace blender::ed::curves
float (*ED_curves_point_normals_array_create(const Curves *curves_id))[3]
{
@ -21,3 +50,10 @@ float (*ED_curves_point_normals_array_create(const Curves *curves_id))[3]
return reinterpret_cast<float(*)[3]>(data);
}
void ED_curves_transverts_create(Curves *curves_id, TransVertStore *tvs)
{
using namespace blender;
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
ed::curves::transverts_from_curves_positions_create(curves, tvs);
}

View File

@ -123,7 +123,7 @@ void fill_selection_true(GMutableSpan selection)
}
}
static bool contains(const VArray<bool> &varray, const bool value)
static bool contains(const VArray<bool> &varray, const IndexRange range_to_check, const bool value)
{
const CommonVArrayInfo info = varray.common_info();
if (info.type == CommonVArrayInfo::Type::Single) {
@ -132,7 +132,7 @@ static bool contains(const VArray<bool> &varray, const bool value)
if (info.type == CommonVArrayInfo::Type::Span) {
const Span<bool> span(static_cast<const bool *>(info.data), varray.size());
return threading::parallel_reduce(
span.index_range(),
range_to_check,
4096,
false,
[&](const IndexRange range, const bool init) {
@ -141,7 +141,7 @@ static bool contains(const VArray<bool> &varray, const bool value)
[&](const bool a, const bool b) { return a || b; });
}
return threading::parallel_reduce(
varray.index_range(),
range_to_check,
2048,
false,
[&](const IndexRange range, const bool init) {
@ -159,10 +159,15 @@ static bool contains(const VArray<bool> &varray, const bool value)
[&](const bool a, const bool b) { return a || b; });
}
bool has_anything_selected(const VArray<bool> &varray, const IndexRange range_to_check)
{
return contains(varray, range_to_check, true);
}
bool has_anything_selected(const bke::CurvesGeometry &curves)
{
const VArray<bool> selection = curves.attributes().lookup<bool>(".selection");
return !selection || contains(selection, true);
return !selection || contains(selection, curves.curves_range(), true);
}
bool has_anything_selected(const GSpan selection)
@ -581,7 +586,7 @@ static bool find_closest_curve_to_screen_co(const Depsgraph &depsgraph,
return b;
});
if (closest_data.index > 0) {
if (closest_data.index >= 0) {
return true;
}

View File

@ -12,6 +12,7 @@ struct UndoType;
struct SelectPick_Params;
struct ViewContext;
struct rcti;
struct TransVertStore;
#ifdef __cplusplus
extern "C" {
@ -32,6 +33,11 @@ void ED_keymap_curves(struct wmKeyConfig *keyconf);
*/
float (*ED_curves_point_normals_array_create(const struct Curves *curves_id))[3];
/**
* Wrapper for `transverts_from_curves_positions_create`.
*/
void ED_curves_transverts_create(struct Curves *curves_id, struct TransVertStore *tvs);
/** \} */
#ifdef __cplusplus
@ -56,6 +62,13 @@ bke::CurvesGeometry primitive_random_sphere(int curves_size, int points_per_curv
VectorSet<Curves *> get_unique_editable_curves(const bContext &C);
void ensure_surface_deformation_node_exists(bContext &C, Object &curves_ob);
/**
* Allocate an array of `TransVert` for cursor/selection snapping (See
* `ED_transverts_create_from_obedit` in `view3d_snap.c`).
* \note: the `TransVert` elements in \a tvs are expected to write to the positions of \a curves.
*/
void transverts_from_curves_positions_create(bke::CurvesGeometry &curves, TransVertStore *tvs);
/* -------------------------------------------------------------------- */
/** \name Poll Functions
* \{ */
@ -93,6 +106,7 @@ bool has_anything_selected(const bke::CurvesGeometry &curves);
* Return true if any element in the span is selected, on either domain with either type.
*/
bool has_anything_selected(GSpan selection);
bool has_anything_selected(const VArray<bool> &varray, IndexRange range_to_check);
/**
* Find curves that have any point selected (a selection factor greater than zero),

View File

@ -61,7 +61,8 @@ void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region)
items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
const int height = ANIM_UI_get_channels_total_height(v2d, items);
v2d->tot.ymin = -height;
const float pad_bottom = BLI_listbase_is_empty(ac->markers) ? 0 : UI_MARKER_MARGIN_Y;
v2d->tot.ymin = -(height + pad_bottom);
/* need to do a view-sync here, so that the keys area doesn't jump around (it must copy this) */
UI_view2d_sync(NULL, ac->area, v2d, V2D_LOCK_COPY);
@ -195,7 +196,8 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region
size_t items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
const int height = ANIM_UI_get_channels_total_height(v2d, items);
v2d->tot.ymin = -height;
const float pad_bottom = BLI_listbase_is_empty(ac->markers) ? 0 : UI_MARKER_MARGIN_Y;
v2d->tot.ymin = -(height + pad_bottom);
/* Draw the manual frame ranges for actions in the background of the dopesheet.
* The action editor has already drawn the range for its action so it's not needed. */

View File

@ -758,8 +758,8 @@ static void init_proportional_edit(TransInfo *t)
else if (t->data_type == &TransConvertType_MeshUV && t->flag & T_PROP_CONNECTED) {
/* Already calculated by uv_set_connectivity_distance. */
}
else if (t->data_type == &TransConvertType_Curve) {
BLI_assert(t->obedit_type == OB_CURVES_LEGACY);
else if (ELEM(t->data_type, &TransConvertType_Curve, &TransConvertType_Curves)) {
BLI_assert(t->obedit_type == OB_CURVES_LEGACY || t->obedit_type == OB_CURVES);
set_prop_dist(t, false);
}
else {

View File

@ -6,6 +6,7 @@
#include "BLI_array.hh"
#include "BLI_index_mask_ops.hh"
#include "BLI_inplace_priority_queue.hh"
#include "BLI_span.hh"
#include "BKE_curves.hh"
@ -23,11 +24,46 @@
namespace blender::ed::transform::curves {
static void calculate_curve_point_distances_for_proportional_editing(
const Span<float3> positions, MutableSpan<float> r_distances)
{
Array<bool, 32> visited(positions.size(), false);
InplacePriorityQueue<float, std::less<float>> queue(r_distances);
while (!queue.is_empty()) {
int64_t index = queue.pop_index();
if (visited[index]) {
continue;
}
visited[index] = true;
/* TODO(Falk): Handle cyclic curves here. */
if (index > 0 && !visited[index - 1]) {
int adjacent = index - 1;
float dist = r_distances[index] + math::distance(positions[index], positions[adjacent]);
if (dist < r_distances[adjacent]) {
r_distances[adjacent] = dist;
queue.priority_changed(adjacent);
}
}
if (index < positions.size() - 1 && !visited[index + 1]) {
int adjacent = index + 1;
float dist = r_distances[index] + math::distance(positions[index], positions[adjacent]);
if (dist < r_distances[adjacent]) {
r_distances[adjacent] = dist;
queue.priority_changed(adjacent);
}
}
}
}
static void createTransCurvesVerts(bContext * /*C*/, TransInfo *t)
{
MutableSpan<TransDataContainer> trans_data_contrainers(t->data_container, t->data_container_len);
Array<Vector<int64_t>> selected_indices_per_object(t->data_container_len);
Array<IndexMask> selection_per_object(t->data_container_len);
const bool use_proportional_edit = (t->flag & T_PROP_EDIT_ALL) != 0;
const bool use_connected_only = (t->flag & T_PROP_CONNECTED) != 0;
/* Count selected elements per object and create TransData structs. */
for (const int i : trans_data_contrainers.index_range()) {
@ -35,10 +71,15 @@ static void createTransCurvesVerts(bContext * /*C*/, TransInfo *t)
Curves *curves_id = static_cast<Curves *>(tc.obedit->data);
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
selection_per_object[i] = ed::curves::retrieve_selected_points(curves,
selected_indices_per_object[i]);
if (use_proportional_edit) {
tc.data_len = curves.point_num;
}
else {
selection_per_object[i] = ed::curves::retrieve_selected_points(
curves, selected_indices_per_object[i]);
tc.data_len = selection_per_object[i].size();
}
tc.data_len = selection_per_object[i].size();
if (tc.data_len > 0) {
tc.data = MEM_cnew_array<TransData>(tc.data_len, __func__);
}
@ -52,34 +93,92 @@ static void createTransCurvesVerts(bContext * /*C*/, TransInfo *t)
}
Curves *curves_id = static_cast<Curves *>(tc.obedit->data);
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
IndexMask selected_indices = selection_per_object[i];
float mtx[3][3], smtx[3][3];
copy_m3_m4(mtx, tc.obedit->object_to_world);
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
MutableSpan<float3> positions = curves.positions_for_write();
threading::parallel_for(selected_indices.index_range(), 1024, [&](const IndexRange range) {
for (const int selection_i : range) {
TransData *td = &tc.data[selection_i];
float *elem = reinterpret_cast<float *>(&positions[selected_indices[selection_i]]);
copy_v3_v3(td->iloc, elem);
copy_v3_v3(td->center, td->iloc);
td->loc = elem;
if (use_proportional_edit) {
const OffsetIndices<int> points_by_curve = curves.points_by_curve();
const VArray<bool> selection = curves.attributes().lookup_or_default<bool>(
".selection", ATTR_DOMAIN_POINT, true);
threading::parallel_for(curves.curves_range(), 512, [&](const IndexRange range) {
Vector<float> closest_distances;
for (const int curve_i : range) {
const IndexRange points = points_by_curve[curve_i];
const bool has_any_selected = ed::curves::has_anything_selected(selection, points);
if (!has_any_selected) {
for (const int point_i : points) {
TransData &td = tc.data[point_i];
td.flag |= TD_NOTCONNECTED;
td.dist = FLT_MAX;
}
if (use_connected_only) {
continue;
}
}
td->flag = TD_SELECTED;
td->ext = nullptr;
closest_distances.reinitialize(points.size());
closest_distances.fill(std::numeric_limits<float>::max());
copy_m3_m3(td->smtx, smtx);
copy_m3_m3(td->mtx, mtx);
}
});
for (const int i : IndexRange(points.size())) {
const int point_i = points[i];
TransData &td = tc.data[point_i];
float3 *elem = &positions[point_i];
copy_v3_v3(td.iloc, *elem);
copy_v3_v3(td.center, td.iloc);
td.loc = *elem;
td.flag = 0;
if (selection[point_i]) {
closest_distances[i] = 0.0f;
td.flag = TD_SELECTED;
}
td.ext = nullptr;
copy_m3_m3(td.smtx, smtx);
copy_m3_m3(td.mtx, mtx);
}
if (use_connected_only) {
calculate_curve_point_distances_for_proportional_editing(
positions.slice(points), closest_distances.as_mutable_span());
for (const int i : IndexRange(points.size())) {
TransData &td = tc.data[points[i]];
td.dist = closest_distances[i];
}
}
}
});
}
else {
const IndexMask selected_indices = selection_per_object[i];
threading::parallel_for(selected_indices.index_range(), 1024, [&](const IndexRange range) {
for (const int selection_i : range) {
TransData *td = &tc.data[selection_i];
float3 *elem = &positions[selected_indices[selection_i]];
copy_v3_v3(td->iloc, *elem);
copy_v3_v3(td->center, td->iloc);
td->loc = *elem;
td->flag = TD_SELECTED;
td->ext = nullptr;
copy_m3_m3(td->smtx, smtx);
copy_m3_m3(td->mtx, mtx);
}
});
}
}
}
static void recalcData_curves(TransInfo *t)
{
Span<TransDataContainer> trans_data_contrainers(t->data_container, t->data_container_len);
const Span<TransDataContainer> trans_data_contrainers(t->data_container, t->data_container_len);
for (const TransDataContainer &tc : trans_data_contrainers) {
Curves *curves_id = static_cast<Curves *>(tc.obedit->data);
bke::CurvesGeometry &curves = curves_id->geometry.wrap();

View File

@ -9,6 +9,7 @@
#include "DNA_armature_types.h"
#include "DNA_curve_types.h"
#include "DNA_curves_types.h"
#include "DNA_lattice_types.h"
#include "DNA_meta_types.h"
#include "DNA_object_types.h"
@ -30,6 +31,7 @@
#include "DEG_depsgraph.h"
#include "ED_armature.h"
#include "ED_curves.h"
#include "ED_transverts.h" /* own include */
@ -181,8 +183,14 @@ static void set_mapped_co(void *vuserdata, int index, const float co[3], const f
bool ED_transverts_check_obedit(const Object *obedit)
{
return (
ELEM(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVES_LEGACY, OB_MBALL));
return (ELEM(obedit->type,
OB_ARMATURE,
OB_LATTICE,
OB_MESH,
OB_SURF,
OB_CURVES_LEGACY,
OB_MBALL,
OB_CURVES));
}
void ED_transverts_create_from_obedit(TransVertStore *tvs, const Object *obedit, const int mode)
@ -481,6 +489,10 @@ void ED_transverts_create_from_obedit(TransVertStore *tvs, const Object *obedit,
bp++;
}
}
else if (obedit->type == OB_CURVES) {
Curves *curves_id = obedit->data;
ED_curves_transverts_create(curves_id, tvs);
}
if (!tvs->transverts_tot && tvs->transverts) {
/* Prevent memory leak. happens for curves/lattices due to

View File

@ -17,6 +17,7 @@
#include "DNA_gpencil_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "BKE_gpencil.h"
@ -42,6 +43,7 @@
#include "MOD_gpencil_util.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
#include "WM_api.h"
@ -254,11 +256,11 @@ static bool isDisabled(GpencilModifierData *md, int UNUSED(userRenderParams))
/* Generic "generateStrokes" callback */
static void generateStrokes(GpencilModifierData *md, Depsgraph *depsgraph, Object *ob)
{
Scene *scene = DEG_get_evaluated_scene(depsgraph);
bGPdata *gpd = ob->data;
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
BKE_gpencil_frame_active_set(depsgraph, gpd);
bGPDframe *gpf = gpl->actframe;
bGPDframe *gpf = BKE_gpencil_frame_retime_get(depsgraph, scene, ob, gpl);
if (gpf == NULL) {
continue;
}

View File

@ -53,7 +53,8 @@ class USDShapeReader : public USDGeomReader {
const char ** /*err_str*/) override;
bool is_time_varying();
virtual bool topology_changed(const Mesh * /*existing_mesh*/, double /*motionSampleTime*/)
virtual bool topology_changed(const Mesh * /*existing_mesh*/,
double /*motionSampleTime*/) override
{
return false;
};