public void FrameCleanup()
        {
            var numBuffers = m_ThreadData->m_NumBuffers;

            if (numBuffers == 0)
            {
                return;
            }

            // These buffers where never used, so they gets returned to the pool at once
            for (int iBuf = 0; iBuf < numBuffers; ++iBuf)
            {
                var mappedBuffer = m_MappedBuffers[iBuf];
                MappedBuffer.UnpackMarker(mappedBuffer.m_Marker, out var operationOffset, out var dataOffset);
                var computeBufferID = mappedBuffer.m_BufferID;
                var computeBuffer   = m_UploadBufferPool.GetBufferFromId(computeBufferID);

                computeBuffer.EndWrite <byte>(0);
                m_UploadBufferPool.PutBufferId(computeBufferID);
            }

            m_MappedBuffers.Dispose();

            StepFrame();
        }
예제 #2
0
        public unsafe ThreadedSparseUploader Begin(int maxDataSizeInBytes, int biggestDataUpload, int maxOperationCount)
        {
#if !DISABLE_HYBRID_RENDERER_V2_FRAME_LIMIT
            if (SystemInfo.supportsAsyncGPUReadback)
            {
                m_LimitingRequests[m_CurrFrame].WaitForCompletion();
                m_LimitingRequests[m_CurrFrame] = AsyncGPUReadback.Request(m_LimitingBuffers[m_CurrFrame]);
            }
#endif

            // First: recover all buffers from the previous frames (if any)
            // TODO: handle change in QualitySettings.maxQueuedFrames
            var currStack = m_FrameReuseBuffers[m_CurrFrame];
            while (currStack.Count != 0)
            {
                var buffer = currStack.Pop();
                m_FreeBuffers.Push(buffer);
            }

            // Second: calculate total size needed this frame, allocate buffers and map what is needed
            var operationSize           = UnsafeUtility.SizeOf <Operation>();
            var maxOperationSizeInBytes = maxOperationCount * operationSize;
            var sizeNeeded = maxOperationSizeInBytes + maxDataSizeInBytes;
            var bufferSizeWithMaxPaddingRemoved = m_BufferChunkSize - operationSize - biggestDataUpload;
            var numBuffersNeeded = (sizeNeeded + bufferSizeWithMaxPaddingRemoved - 1) / bufferSizeWithMaxPaddingRemoved;
            EnsurePreallocatedComputeBuffers(numBuffersNeeded);

            if (numBuffersNeeded < 0)
            {
                numBuffersNeeded = 0;
            }

            m_MappedBuffers = new NativeArray <MappedBuffer>(numBuffersNeeded, Allocator.Temp, NativeArrayOptions.UninitializedMemory);

            for (int i = 0; i < numBuffersNeeded; ++i)
            {
                var id     = m_FreeBuffers.Pop();
                var cb     = m_UploadBuffers[id];
                var data   = cb.BeginWrite <byte>(0, m_BufferChunkSize);
                var marker = MappedBuffer.PackMarker(0, m_BufferChunkSize);
                m_MappedBuffers[i] = new MappedBuffer
                {
                    m_Data     = (byte *)data.GetUnsafePtr(),
                    m_Marker   = marker,
                    m_BufferID = id,
                };
            }

            m_ThreadData->m_Buffers    = (MappedBuffer *)m_MappedBuffers.GetUnsafePtr();
            m_ThreadData->m_NumBuffers = numBuffersNeeded;

            // TODO: set safety handle on thread data
            return(new ThreadedSparseUploader
            {
                m_Data = m_ThreadData
            });
        }
        public ThreadedSparseUploader Begin(int maxDataSizeInBytes, int biggestDataUpload, int maxOperationCount)
        {
            // First: recover all buffers from the previous frames (if any)
            RecoverBuffers();

            // Second: calculate total size needed this frame, allocate buffers and map what is needed
            var operationSize           = UnsafeUtility.SizeOf <Operation>();
            var maxOperationSizeInBytes = maxOperationCount * operationSize;
            var sizeNeeded = maxOperationSizeInBytes + maxDataSizeInBytes;
            var bufferSizeWithMaxPaddingRemoved = m_BufferChunkSize - operationSize - biggestDataUpload;
            var numBuffersNeeded = (sizeNeeded + bufferSizeWithMaxPaddingRemoved - 1) / bufferSizeWithMaxPaddingRemoved;

            if (numBuffersNeeded < 0)
            {
                numBuffersNeeded = 0;
            }

            m_MappedBuffers = new NativeArray <MappedBuffer>(numBuffersNeeded, Allocator.Temp, NativeArrayOptions.UninitializedMemory);

            for (int i = 0; i < numBuffersNeeded; ++i)
            {
                var id     = m_UploadBufferPool.GetBufferId();
                var cb     = m_UploadBufferPool.GetBufferFromId(id);
                var data   = cb.BeginWrite <byte>(0, m_BufferChunkSize);
                var marker = MappedBuffer.PackMarker(0, m_BufferChunkSize);
                m_MappedBuffers[i] = new MappedBuffer
                {
                    m_Data     = (byte *)data.GetUnsafePtr(),
                    m_Marker   = marker,
                    m_BufferID = id,
                };
            }

            m_ThreadData->m_Buffers    = (MappedBuffer *)m_MappedBuffers.GetUnsafePtr();
            m_ThreadData->m_NumBuffers = numBuffersNeeded;

            // TODO: set safety handle on thread data
            return(new ThreadedSparseUploader
            {
                m_Data = m_ThreadData
            });
        }
        public void EndAndCommit(ThreadedSparseUploader tsu)
        {
            var numBuffers = m_ThreadData->m_NumBuffers;
            var frameData  = m_FreeFrameData.Count > 0 ? m_FreeFrameData.Pop() : new FrameData();

            for (int iBuf = 0; iBuf < numBuffers; ++iBuf)
            {
                var mappedBuffer = m_MappedBuffers[iBuf];
                MappedBuffer.UnpackMarker(mappedBuffer.m_Marker, out var operationOffset, out var dataOffset);
                var numOps          = (int)(operationOffset / UnsafeUtility.SizeOf <Operation>());
                var computeBufferID = mappedBuffer.m_BufferID;
                var computeBuffer   = m_UploadBufferPool.GetBufferFromId(computeBufferID);

                if (numOps > 0)
                {
                    computeBuffer.EndWrite <byte>(m_BufferChunkSize);

                    DispatchUploads(numOps, computeBuffer);

                    frameData.m_Buffers.Push(computeBufferID);
                }
                else
                {
                    computeBuffer.EndWrite <byte>(0);
                    m_UploadBufferPool.PutBufferId(computeBufferID);
                }
            }

            if (SystemInfo.supportsAsyncGPUReadback)
            {
                var fenceBufferId = m_FenceBufferPool.GetBufferId();
                frameData.m_FenceBuffer = fenceBufferId;
                frameData.m_Fence       = AsyncGPUReadback.Request(m_FenceBufferPool.GetBufferFromId(fenceBufferId));
            }

            m_FrameData.Add(frameData);

            m_MappedBuffers.Dispose();

            StepFrame();
        }
예제 #5
0
        public void EndAndCommit(ThreadedSparseUploader tsu)
        {
            var numBuffers = m_ThreadData->m_NumBuffers;

            for (int iBuf = 0; iBuf < numBuffers; ++iBuf)
            {
                var mappedBuffer = m_MappedBuffers[iBuf];
                MappedBuffer.UnpackMarker(mappedBuffer.m_Marker, out var operationOffset, out var dataOffset);
                var numOps          = (int)(operationOffset / UnsafeUtility.SizeOf <Operation>());
                var computeBufferID = mappedBuffer.m_BufferID;
                var computeBuffer   = m_UploadBuffers[computeBufferID];

                if (numOps > 0)
                {
                    computeBuffer.EndWrite <byte>(m_BufferChunkSize);

                    DispatchUploads(numOps, computeBuffer);

                    m_FrameReuseBuffers[m_CurrFrame].Push(computeBufferID);
                }
                else
                {
                    computeBuffer.EndWrite <byte>(0);
                    m_FreeBuffers.Push(computeBufferID);
                }
            }

            m_MappedBuffers.Dispose();

            m_CurrFrame += 1;
            if (m_CurrFrame >= m_NumBufferedFrames)
            {
                m_CurrFrame = 0;
            }
            // TODO: release safety handle of thread data
            m_ThreadData->m_Buffers    = null;
            m_ThreadData->m_NumBuffers = 0;
            m_ThreadData->m_CurrBuffer = 0;
        }