// 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();
            }
예제 #3
0
            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++;
            }