// This is expected to be called no more than once per frame public void SendUpdates() { if (m_UpdateRangesEnqueued == 0) { return; } if (m_UpdateRangesSaturated) { uint updateSize = m_UpdateRangeMax - m_UpdateRangeMin; m_UpdateRangesEnqueued = 1; updateRanges[(int)m_UpdateRangesBatchStart] = new GfxUpdateBufferRange() { source = new UIntPtr(cpuData.Slice((int)m_UpdateRangeMin, (int)updateSize).GetUnsafeReadOnlyPtr()), offsetFromWriteStart = m_UpdateRangeMin * m_ElemStride, size = updateSize * m_ElemStride }; } // Send to the GPU, if the minimum affected byte address is not zero, we need to adjust the range entries // to factor out that offset as the 'offsetFromWriteStart' member is refering to the buffer lock position // not the start of the GPU buffer uint minByte = m_UpdateRangeMin * m_ElemStride; uint maxByte = m_UpdateRangeMax * m_ElemStride; if (minByte > 0) { for (uint i = 0; i < m_UpdateRangesEnqueued; i++) { int index = (int)(i + m_UpdateRangesBatchStart); updateRanges[index] = new GfxUpdateBufferRange() { source = updateRanges[index].source, offsetFromWriteStart = updateRanges[index].offsetFromWriteStart - minByte, size = updateRanges[index].size }; } } gpuData?.UpdateRanges(updateRanges.Slice((int)m_UpdateRangesBatchStart, (int)m_UpdateRangesEnqueued), (int)minByte, (int)maxByte); // Reset state for upcoming updates m_UpdateRangeMin = uint.MaxValue; m_UpdateRangeMax = 0; m_UpdateRangesEnqueued = 0; m_UpdateRangesBatchStart = (m_UpdateRangesBatchStart + m_UpdateRangePoolSize); if (m_UpdateRangesBatchStart >= updateRanges.Length) { m_UpdateRangesBatchStart = 0; } m_UpdateRangesSaturated = false; }
public void SendFullRange() { uint fullRangeBytes = (uint)(cpuData.Length * m_ElemStride); updateRanges[(int)m_UpdateRangesBatchStart] = new GfxUpdateBufferRange() { source = new UIntPtr(cpuData.GetUnsafeReadOnlyPtr()), offsetFromWriteStart = 0, size = fullRangeBytes }; gpuData?.UpdateRanges(updateRanges.Slice((int)m_UpdateRangesBatchStart, 1), (int)0, (int)fullRangeBytes); ResetUpdateState(); }
public void RegisterUpdate(uint start, uint size) { Debug.Assert((ulong)(start + size) <= (ulong)((long)this.cpuData.Length)); int num = (int)(this.m_UpdateRangesBatchStart + this.m_UpdateRangesEnqueued); bool flag = this.m_UpdateRangesEnqueued > 0u; if (flag) { int index = num - 1; GfxUpdateBufferRange gfxUpdateBufferRange = this.updateRanges[index]; uint num2 = start * this.m_ElemStride; bool flag2 = gfxUpdateBufferRange.offsetFromWriteStart + gfxUpdateBufferRange.size == num2; if (flag2) { this.updateRanges[index] = new GfxUpdateBufferRange { source = gfxUpdateBufferRange.source, offsetFromWriteStart = gfxUpdateBufferRange.offsetFromWriteStart, size = gfxUpdateBufferRange.size + size * this.m_ElemStride }; this.m_UpdateRangeMax = Math.Max(this.m_UpdateRangeMax, start + size); return; } } this.m_UpdateRangeMin = Math.Min(this.m_UpdateRangeMin, start); this.m_UpdateRangeMax = Math.Max(this.m_UpdateRangeMax, start + size); bool flag3 = this.m_UpdateRangesEnqueued == this.m_UpdateRangePoolSize; if (flag3) { this.m_UpdateRangesSaturated = true; } else { UIntPtr source = new UIntPtr(this.cpuData.Slice((int)start, (int)size).GetUnsafeReadOnlyPtr <T>()); this.updateRanges[num] = new GfxUpdateBufferRange { source = source, offsetFromWriteStart = start * this.m_ElemStride, size = size * this.m_ElemStride }; this.m_UpdateRangesEnqueued += 1u; } }
public void RegisterUpdate(uint start, uint size) { Debug.Assert(start + size <= cpuData.Length); int rangeIndex = (int)(m_UpdateRangesBatchStart + m_UpdateRangesEnqueued); if (m_UpdateRangesEnqueued > 0) { // If this update chains with the previous one, just grow the previous one int lastIndex = rangeIndex - 1; var lastRange = updateRanges[lastIndex]; uint startBytes = start * m_ElemStride; if (lastRange.offsetFromWriteStart + lastRange.size == startBytes) { updateRanges[lastIndex] = new GfxUpdateBufferRange() { source = lastRange.source, offsetFromWriteStart = lastRange.offsetFromWriteStart, size = lastRange.size + size * m_ElemStride }; m_UpdateRangeMax = Math.Max(m_UpdateRangeMax, start + size); return; } } m_UpdateRangeMin = Math.Min(m_UpdateRangeMin, start); m_UpdateRangeMax = Math.Max(m_UpdateRangeMax, start + size); if (m_UpdateRangesEnqueued == m_UpdateRangePoolSize) { m_UpdateRangesSaturated = true; return; // Reached the max for this frame, ignore any more notifications, and just upload the entire affected regions including any holes inbetween } var cpuDataSlice = new UIntPtr(cpuData.Slice((int)start, (int)size).GetUnsafeReadOnlyPtr()); updateRanges[rangeIndex] = new GfxUpdateBufferRange() { source = cpuDataSlice, offsetFromWriteStart = start * m_ElemStride, size = size * m_ElemStride }; m_UpdateRangesEnqueued++; }