/// <summary> /// Checks if a given GPU virtual memory range is mapped to the same physical regions /// as the specified physical memory multi-range. /// </summary> /// <param name="range">Physical memory multi-range</param> /// <param name="va">GPU virtual memory address</param> /// <returns>True if the virtual memory region is mapped into the specified physical one, false otherwise</returns> public bool CompareRange(MultiRange range, ulong va) { va &= ~PageMask; for (int i = 0; i < range.Count; i++) { MemoryRange currentRange = range.GetSubRange(i); ulong address = currentRange.Address & ~PageMask; ulong endAddress = (currentRange.EndAddress + PageMask) & ~PageMask; while (address < endAddress) { if (Translate(va) != address) { return(false); } va += PageSize; address += PageSize; } } return(true); }
public override void FromJson(Dictionary <string, Node> nodes, string data) { LevelsData d = JsonConvert.DeserializeObject <LevelsData>(data); SetBaseNodeDate(d); range = d.range; }
/// <summary> /// Constructs a new instance of the cached GPU texture. /// </summary> /// <param name="context">GPU context that the texture belongs to</param> /// <param name="info">Texture information</param> /// <param name="sizeInfo">Size information of the texture</param> /// <param name="range">Physical memory ranges where the texture data is located</param> /// <param name="scaleMode">The scale mode to initialize with. If scaled, the texture's data is loaded immediately and scaled up</param> public Texture(GpuContext context, TextureInfo info, SizeInfo sizeInfo, MultiRange range, TextureScaleMode scaleMode) { ScaleFactor = 1f; // Texture is first loaded at scale 1x. ScaleMode = scaleMode; InitializeTexture(context, info, sizeInfo, range); }
/// <summary> /// Handles removal of textures written to a memory region being unmapped. /// </summary> /// <param name="sender">Sender object</param> /// <param name="e">Event arguments</param> public void MemoryUnmappedHandler(object sender, UnmapEventArgs e) { Texture[] overlaps = new Texture[10]; int overlapCount; MultiRange unmapped = ((MemoryManager)sender).GetPhysicalRegions(e.Address, e.Size); lock (_textures) { overlapCount = _textures.FindOverlaps(unmapped, ref overlaps); } for (int i = 0; i < overlapCount; i++) { overlaps[i].Unmapped(unmapped); } // If any range was previously unmapped, we also need to purge // all partially mapped texture, as they might be fully mapped now. for (int i = 0; i < unmapped.Count; i++) { if (unmapped.GetSubRange(i).Address == MemoryManager.PteUnmapped) { lock (_partiallyMappedTextures) { foreach (var texture in _partiallyMappedTextures) { texture.Unmapped(unmapped); } } break; } } }
public LevelsNode(int w, int h, GraphPixelType p = GraphPixelType.RGBA) { Name = "Levels"; Id = Guid.NewGuid().ToString(); width = w; height = h; tileX = tileY = 1; range = new MultiRange(); previewProcessor = new BasicImageRenderer(); processor = new LevelsProcessor(); internalPixelType = p; input = new NodeInput(NodeType.Color | NodeType.Gray, this, "Image Input"); Output = new NodeOutput(NodeType.Color | NodeType.Gray, this); input.OnInputAdded += Input_OnInputAdded; input.OnInputChanged += Input_OnInputChanged; input.OnInputRemoved += Input_OnInputRemoved; Inputs = new List <NodeInput>(); Inputs.Add(input); Outputs = new List <NodeOutput>(); Outputs.Add(Output); }
/// <summary> /// Writes data to the application process, using the supplied callback method. /// </summary> /// <param name="range">Ranges of physical memory where the data is located</param> /// <param name="data">Data to be written</param> /// <param name="writeCallback">Callback method that will perform the write</param> private static void WriteImpl(MultiRange range, ReadOnlySpan <byte> data, WriteCallback writeCallback) { if (range.Count == 1) { var singleRange = range.GetSubRange(0); if (singleRange.Address != MemoryManager.PteUnmapped) { writeCallback(singleRange.Address, data); } } else { int offset = 0; for (int i = 0; i < range.Count; i++) { var currentRange = range.GetSubRange(i); int size = (int)currentRange.Size; if (currentRange.Address != MemoryManager.PteUnmapped) { writeCallback(currentRange.Address, data.Slice(offset, size)); } offset += size; } } }
/// <summary> /// Gets a span of data from the application process. /// </summary> /// <param name="range">Ranges of physical memory where the data is located</param> /// <param name="tracked">True if read tracking is triggered on the span</param> /// <returns>A read only span of the data at the specified memory location</returns> public ReadOnlySpan <byte> GetSpan(MultiRange range, bool tracked = false) { if (range.Count == 1) { var singleRange = range.GetSubRange(0); if (singleRange.Address != MemoryManager.PteUnmapped) { return(_cpuMemory.GetSpan(singleRange.Address, (int)singleRange.Size, tracked)); } } Span <byte> data = new byte[range.GetSize()]; int offset = 0; for (int i = 0; i < range.Count; i++) { var currentRange = range.GetSubRange(i); int size = (int)currentRange.Size; if (currentRange.Address != MemoryManager.PteUnmapped) { _cpuMemory.GetSpan(currentRange.Address, size, tracked).CopyTo(data.Slice(offset, size)); } offset += size; } return(data); }
/// <summary> /// Gets a writable region from GPU mapped memory. /// </summary> /// <param name="range">Range</param> /// <param name="tracked">True if write tracking is triggered on the span</param> /// <returns>A writable region with the data at the specified memory location</returns> public WritableRegion GetWritableRegion(MultiRange range, bool tracked = false) { if (range.Count == 1) { MemoryRange subrange = range.GetSubRange(0); return(GetWritableRegion(subrange.Address, (int)subrange.Size, tracked)); } else { Memory <byte> memory = new byte[range.GetSize()]; int offset = 0; for (int i = 0; i < range.Count; i++) { var currentRange = range.GetSubRange(i); int size = (int)currentRange.Size; if (currentRange.Address != MemoryManager.PteUnmapped) { GetSpan(currentRange.Address, size).CopyTo(memory.Span.Slice(offset, size)); } offset += size; } return(new WritableRegion(new MultiRangeWritableBlock(range, this), 0, memory, tracked)); } }
private MultiRange R(int begin, int end) { var range = new MultiRange { new Range(begin, end) }; return(range); }
public override void FromJson(string data) { LevelsData d = JsonConvert.DeserializeObject <LevelsData>(data); SetBaseNodeDate(d); //to ensure backwards compat with older multi range size range = new MultiRange(d.range.min, d.range.mid, d.range.max); }
public void RestoreSnapshot(MultiRange selectedRows) { lock (selectedIndices) { UnselectAll(); selectedIndices.UnionWith(selectedRows); RaiseSelectionChanged(); } }
private MultiRange R(int index) { var range = new MultiRange { new Range(index, index + 1) }; return(range); }
public void Default() { var range = new MultiRange(); Assert.Equal(0, range.Count); Assert.Equal(new Range[0], range.GetRanges()); Assert.False(range.Contains(42)); }
public void AddRange_Empty() { var range = new MultiRange(); range.Add(new Range(10, 20)); Assert.Equal(10, range.Count); Assert.Equal(new[] { R(10, 20) }, range.GetRanges()); }
public void Add() { var range = new MultiRange(); range.Add(42); Assert.Equal(1, range.Count); Assert.Equal(new[] { R(42) }, range.GetRanges()); Assert.True(range.Contains(42)); }
public void Copy_Empty() { var range = new MultiRange(); var copy = new MultiRange(range); Assert.Equal(0, copy.Count); Assert.Equal(new Range[0], copy.GetRanges()); Assert.False(copy.Contains(42)); }
public void Remove_Mid() { var range = new MultiRange { 10, 11, 12, 13, 14 }; range.Remove(12); Assert.Equal(4, range.Count); Assert.Equal(new[] { R(10, 12), R(13, 15) }, range.GetRanges()); }
public override void FromJson(Dictionary <string, Node> nodes, string data) { LevelsData d = JsonConvert.DeserializeObject <LevelsData>(data); SetBaseNodeDate(d); range = d.range; SetConnections(nodes, d.outputs); OnWidthHeightSet(); }
public void Add_Mid() { var range = new MultiRange(); range.Add(10); range.Add(12); range.Add(11); Assert.Equal(3, range.Count); Assert.Equal(new[] { R(10, 13) }, range.GetRanges()); }
public void Clear() { var range = new MultiRange { 10, 11, 12, 23, 24, 25 }; range.Clear(); Assert.Equal(0, range.Count); Assert.Equal(new Range[0], range.GetRanges()); }
public void RemoveRange_Super() { var range = new MultiRange { 10, 11, 12, 13, 14 }; range.Remove(new Range(8, 16)); Assert.Equal(0, range.Count); Assert.Equal(new Range[0], range.GetRanges()); }
public void RemoveRange_End() { var range = new MultiRange { 10, 11, 12, 13, 14 }; range.Remove(new Range(13, 15)); Assert.Equal(3, range.Count); Assert.Equal(new[] { R(10, 13) }, range.GetRanges()); }
public void AddRange_Super() { var range = new MultiRange { 10, 11 }; range.Add(new Range(5, 15)); Assert.Equal(10, range.Count); Assert.Equal(new[] { R(5, 15) }, range.GetRanges()); }
public void Remove_NotContained() { var range = new MultiRange { 10, 11, 12 }; range.Remove(42); Assert.Equal(3, range.Count); Assert.Equal(new[] { R(10, 13) }, range.GetRanges()); }
public void AddRange_OverlappedEnd() { var range = new MultiRange { 10, 11, 12 }; range.Add(new Range(11, 15)); Assert.Equal(5, range.Count); Assert.Equal(new[] { R(10, 15) }, range.GetRanges()); }
public void AddRange_OverlappedBegin() { var range = new MultiRange { 7, 8, 9 }; range.Add(new Range(5, 8)); Assert.Equal(5, range.Count); Assert.Equal(new[] { R(5, 10) }, range.GetRanges()); }
public void Remove_End() { var range = new MultiRange { 10, 11, 12 }; range.Remove(12); Assert.Equal(2, range.Count); Assert.Equal(new[] { R(10, 12) }, range.GetRanges()); }
public void RemoveRange_Mid() { var range = new MultiRange { 10, 11, 12, 13, 14 }; range.Remove(new Range(11, 14)); Assert.Equal(2, range.Count); Assert.Equal(new[] { R(10), R(14) }, range.GetRanges()); }
/// <summary> /// Common texture initialization method. /// This sets the context, info and sizeInfo fields. /// Other fields are initialized with their default values. /// </summary> /// <param name="context">GPU context that the texture belongs to</param> /// <param name="info">Texture information</param> /// <param name="sizeInfo">Size information of the texture</param> /// <param name="range">Physical memory ranges where the texture data is located</param> private void InitializeTexture(GpuContext context, TextureInfo info, SizeInfo sizeInfo, MultiRange range) { _context = context; _sizeInfo = sizeInfo; Range = range; SetInfo(info); _viewStorage = this; _views = new List <Texture>(); }
/// <summary> /// Obtains a memory tracking handle for the given virtual region. This should be disposed when finished with. /// </summary> /// <param name="range">Ranges of physical memory where the data is located</param> /// <returns>The memory tracking handle</returns> public GpuRegionHandle BeginTracking(MultiRange range) { var cpuRegionHandles = new CpuRegionHandle[range.Count]; for (int i = 0; i < range.Count; i++) { var currentRange = range.GetSubRange(i); cpuRegionHandles[i] = _cpuMemory.BeginTracking(currentRange.Address, currentRange.Size); } return(new GpuRegionHandle(cpuRegionHandles)); }