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(); }
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(); }
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; }