diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/CountFilter.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/CountFilter.java index f6844e684..7c6767bf2 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/CountFilter.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/CountFilter.java @@ -3,6 +3,7 @@ package com.fastasyncworldedit.core.extent.filter; import com.fastasyncworldedit.core.extent.filter.block.FilterBlock; import com.fastasyncworldedit.core.internal.simd.VectorizedFilter; import jdk.incubator.vector.ShortVector; +import jdk.incubator.vector.VectorMask; public class CountFilter extends ForkedFilter implements VectorizedFilter { @@ -36,8 +37,8 @@ public class CountFilter extends ForkedFilter implements Vectorized } @Override - public ShortVector applyVector(final ShortVector get, final ShortVector set) { - total += set.length(); + public ShortVector applyVector(final ShortVector get, final ShortVector set, VectorMask mask) { + total += mask.trueCount(); return set; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/LinkedFilter.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/LinkedFilter.java index 26700ccc5..ff57a4625 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/LinkedFilter.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/LinkedFilter.java @@ -6,6 +6,7 @@ import com.fastasyncworldedit.core.queue.Filter; import com.fastasyncworldedit.core.queue.IChunk; import com.sk89q.worldedit.regions.Region; import jdk.incubator.vector.ShortVector; +import jdk.incubator.vector.VectorMask; import org.jetbrains.annotations.Nullable; /** @@ -77,9 +78,9 @@ public sealed class LinkedFilter implements } @Override - public ShortVector applyVector(final ShortVector get, final ShortVector set) { - ShortVector res = getLeft().applyVector(get, set); - return getRight().applyVector(get, res); + public ShortVector applyVector(final ShortVector get, final ShortVector set, VectorMask mask) { + ShortVector res = getLeft().applyVector(get, set, mask); + return getRight().applyVector(get, res, mask); } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/MaskFilter.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/MaskFilter.java index ac31938e2..2ce1527df 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/MaskFilter.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/MaskFilter.java @@ -82,11 +82,10 @@ public class MaskFilter extends DelegateFilter { } @Override - public ShortVector applyVector(final ShortVector get, final ShortVector set) { + public ShortVector applyVector(final ShortVector get, final ShortVector set, VectorMask mask) { final T parent = getParent(); VectorMask masked = vectorizedMask.compareVector(set, get); - ShortVector res = parent.applyVector(get, set); - res = set.blend(res, masked); + ShortVector res = parent.applyVector(get, set, mask.and(masked)); VectorMask changed = res.compare(VectorOperators.NE, set); changes.getAndAdd(changed.trueCount()); return res; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/SimdSupport.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/SimdSupport.java index 5f2d6a711..eefdc1929 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/SimdSupport.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/SimdSupport.java @@ -14,6 +14,7 @@ import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockTypesCache; import jdk.incubator.vector.ShortVector; +import jdk.incubator.vector.VectorMask; import jdk.incubator.vector.VectorOperators; import javax.annotation.Nullable; @@ -101,8 +102,9 @@ public class SimdSupport { } @Override - public ShortVector applyVector(final ShortVector get, final ShortVector set) { - return ShortVector.broadcast(ShortVector.SPECIES_PREFERRED, ordinal); + public ShortVector applyVector(final ShortVector get, final ShortVector set, VectorMask mask) { + // only change the lanes the mask dictates us to change, keep the rest + return set.blend(ShortVector.broadcast(ShortVector.SPECIES_PREFERRED, ordinal), mask); } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorizedCharFilterBlock.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorizedCharFilterBlock.java index 5c15da22a..9f557b134 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorizedCharFilterBlock.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorizedCharFilterBlock.java @@ -4,6 +4,7 @@ import com.fastasyncworldedit.core.extent.filter.block.CharFilterBlock; import com.fastasyncworldedit.core.queue.Filter; import com.sk89q.worldedit.extent.Extent; import jdk.incubator.vector.ShortVector; +import jdk.incubator.vector.VectorMask; import jdk.incubator.vector.VectorSpecies; public class VectorizedCharFilterBlock extends CharFilterBlock { @@ -18,15 +19,17 @@ public class VectorizedCharFilterBlock extends CharFilterBlock { throw new IllegalStateException("Unexpected VectorizedCharFilterBlock " + filter); } final VectorSpecies species = ShortVector.SPECIES_PREFERRED; + // TODO can we avoid eager initSet? initSet(); // set array is null before char[] setArr = this.setArr; assert setArr != null; char[] getArr = this.getArr; // assume setArr.length == getArr.length == 4096 + VectorMask affectAll = species.maskAll(true); for (int i = 0; i < 4096; i += species.length()) { ShortVector set = ShortVector.fromCharArray(species, setArr, i); ShortVector get = ShortVector.fromCharArray(species, getArr, i); - ShortVector res = vecFilter.applyVector(get, set); + ShortVector res = vecFilter.applyVector(get, set, affectAll); res.intoCharArray(setArr, i); } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorizedFilter.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorizedFilter.java index 7357bbd59..b0801fcd0 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorizedFilter.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorizedFilter.java @@ -2,7 +2,18 @@ package com.fastasyncworldedit.core.internal.simd; import com.fastasyncworldedit.core.queue.Filter; import jdk.incubator.vector.ShortVector; +import jdk.incubator.vector.VectorMask; public interface VectorizedFilter extends Filter { - ShortVector applyVector(ShortVector get, ShortVector set); + + /** + * Applies a filter to a vector pair of get and set. + * + * @param get the get vector + * @param set the set vector + * @param mask the mask with the lanes set to true which should be affected by the filter + * @return the resulting set vector. + */ + ShortVector applyVector(ShortVector get, ShortVector set, VectorMask mask); + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorizedMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorizedMask.java index 0f453f32b..a6fd18b48 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorizedMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorizedMask.java @@ -3,6 +3,7 @@ package com.fastasyncworldedit.core.internal.simd; import com.fastasyncworldedit.core.queue.IChunk; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.sk89q.worldedit.world.block.BlockTypesCache; import jdk.incubator.vector.ShortVector; import jdk.incubator.vector.VectorMask; import jdk.incubator.vector.VectorSpecies; @@ -31,10 +32,22 @@ public interface VectorizedMask { } } + /** + * {@return the set vector with all lanes that do not match this mask set to 0} + * + * @param set the set vector + * @param get the get vector + */ default ShortVector processVector(ShortVector set, ShortVector get) { - return set.blend(0, compareVector(set, get).not()); + return set.blend(BlockTypesCache.ReservedIDs.__RESERVED__, compareVector(set, get).not()); } + /** + * {@return a mask with all lanes set that match this mask} + * + * @param set the set vector + * @param get the get vector + */ VectorMask compareVector(ShortVector set, ShortVector get); }