/// <summary> Creates texture and pass to plugin. </summary> /// <param name="height"> The height. </param> /// <param name="width"> The width. </param> public void CreateTextureAndPassToPlugin(int height, int width) { // Create a texture tex = new Texture2D(height, width, TextureFormat.RGBAFloat, false, true); // Use bilinear, point caused issues with striations in the depth image // bilinear also causes issues but they are handled in the DepthMapOcclusion.shader tex.filterMode = FilterMode.Bilinear; // Call Apply() so it's actually uploaded to the GPU tex.Apply(); // Pass texture pointer to the plugin KernelInterop.SetTextureFromUnity(tex.GetNativeTexturePtr(), height, width); }
/// <summary> /// Tries to release all allocated resources. /// </summary> /// <param name="rioHandle">The object that provides work with Winsock registered I/O extensions.</param> /// <param name="kernelErrorCode">Contains <c>0</c> if operation was successful, error code otherwise.</param> /// <returns><c>true</c> if operation was successful, <c>false</c> otherwise.</returns> public unsafe Boolean TryRelease(RIOHandle rioHandle, out UInt32 kernelErrorCode) { // 0 deregister buffer with Registered I/O extension { rioHandle.DeregisterBuffer(bufferId); } // 1 try free memory { var freeResult = KernelInterop.VirtualFree((void *)buffer, 0, KernelInterop.MEM_RELEASE); if (freeResult == false) { kernelErrorCode = KernelInterop.GetLastError(); return(false); } } // 2 success kernelErrorCode = 0; return(true); }
/// <summary> /// Tries to create a new instance of the <see cref="IocpWorker" />. /// </summary> /// <param name="rioHandle">The object that provides work with Winsock registered I/O extensions.</param> /// <param name="processorIndex">The index of the processor.</param> /// <param name="segmentLength">The length of the segment.</param> /// <param name="segmentsCount">The count of the segments.</param> /// <returns> /// An instance of <see cref="TryResult{T}" /> which encapsulates result of the operation. /// <see cref="TryResult{T}.Success" /> contains <c>true</c> if operation was successful, <c>false</c> otherwise. /// <see cref="TryResult{T}.Result" /> contains valid object if operation was successful, <c>null</c> otherwise. /// </returns> public static unsafe TryResult <IocpWorker> TryCreate(RIOHandle rioHandle, Int32 processorIndex, UInt32 segmentLength, UInt32 segmentsCount) { #region 0 try create completion port var completionPort = KernelInterop.CreateIoCompletionPort(KernelInterop.INVALID_HANDLE_VALUE, IntPtr.Zero, UIntPtr.Zero, 0); // check if operation has succeed if (completionPort == IntPtr.Zero) { // get error code var kernelErrorCode = (KernelErrorCode)KernelInterop.GetLastError(); // return fail result TryResult <IocpWorker> .CreateFail(kernelErrorCode); } #endregion #region 1 try create completion queue // compose completion method structure var completionMethod = new RIO_NOTIFICATION_COMPLETION { // set type to IOCP Type = RIO_NOTIFICATION_COMPLETION_TYPE.RIO_IOCP_COMPLETION, union = { // set IOCP parameters Iocp = new RIO_NOTIFICATION_COMPLETION.UNION.IOCP { // set completion port IocpHandle = completionPort, // set completion key CompletionKey = (UInt64)processorIndex, Overlapped = (NativeOverlapped *)-1 } } }; // try create completion queue var completionQueue = rioHandle.CreateCompletionQueue(maxOutsandingCompletions, completionMethod); if (completionQueue == WinsockInterop.RIO_INVALID_CQ) { // get error code var winsockErrorCode = (WinsockErrorCode)WinsockInterop.WSAGetLastError(); // return fail result TryResult <IocpWorker> .CreateFail(winsockErrorCode); } #endregion #region 2 try create buffer pool var tryCreateBufferPool = RIOBufferPool.TryCreate(rioHandle, segmentLength, segmentsCount); if (tryCreateBufferPool.Success == false) { // return result return(TryResult <IocpWorker> .CreateFail(tryCreateBufferPool.KernelErrorCode, tryCreateBufferPool.WinsockErrorCode)); } #endregion // success var result = new IocpWorker(rioHandle, processorIndex, completionPort, completionQueue, tryCreateBufferPool.Result); // return success result return(TryResult <IocpWorker> .CreateSuccess(result)); }
private unsafe void Process() { const Int32 maxResults = 1024; RIORESULT *results = stackalloc RIORESULT[maxResults]; /* * RIOPooledSegment cachedBadBuffer = worker.bufferPool.GetBuffer(); * Buffer.BlockCopy(_badResponseBytes, 0, cachedBadBuffer.Buffer, cachedBadBuffer.Offset, _badResponseBytes.Length); * cachedBadBuffer.RioBuffer.Length = (uint)_badResponseBytes.Length; * worker.cachedBad = cachedBadBuffer.RioBuffer; * * RIOPooledSegment cachedBusyBuffer = worker.bufferPool.GetBuffer(); * Buffer.BlockCopy(_busyResponseBytes, 0, cachedBusyBuffer.Buffer, cachedBusyBuffer.Offset, _busyResponseBytes.Length); * cachedBusyBuffer.RioBuffer.Length = (uint)_busyResponseBytes.Length; * worker.cachedBusy = cachedBusyBuffer.RioBuffer; */ //while (!cancellationToken.IsCancellationRequested) while (true) { // try register method to use for notification behavior with the I/O completion queue var notifyResult = (WinsockErrorCode)RioHandle.Notify(CompletionQueue); if (notifyResult != WinsockErrorCode.None) { // TODO: fail } // try dequeue the I/O completion packet from the specified I/O completion port UInt32 bytesCount; UIntPtr completionKey; NativeOverlapped *overlapped; var getQueuedCompletionStatusResult = KernelInterop.GetQueuedCompletionStatus(CompletionPort, out bytesCount, out completionKey, out overlapped, UInt32.MaxValue); if (getQueuedCompletionStatusResult == false) { // TODO: fail } // try remove entries from the I/O completion queue var resultsCount = RioHandle.DequeueCompletion(CompletionQueue, (IntPtr)results, maxResults); /* * if (resultsCount == RIOHandle.RIO_CORRUPT_CQ.) * { * // TODO: fail * } */ var activatedCompletionPort = false; while (resultsCount > 0) { for (var resultIndex = 0; resultIndex < resultsCount; resultIndex++) { // get RIORESULT var result = results[resultIndex]; // TODO : wtf ??? // if (result.RequestContext >= 0) TcpConnection connection; if (Connections.TryGetValue(result.SocketContext.ToUInt64(), out connection)) { //connection.CompleteReceive(result.RequestContext, result.BytesTransferred); } } if (!activatedCompletionPort) { notifyResult = (WinsockErrorCode)RioHandle.Notify(CompletionQueue); if (notifyResult != WinsockErrorCode.None) { // TODO: fail } activatedCompletionPort = true; } } } /* * else * { * var error = GetLastError(); * if (error != 258) * { * throw new Exception(string.Format("ERROR: GetQueuedCompletionStatusEx returned {0}", error)); * } * } * * cachedBadBuffer.Dispose(); * cachedBusyBuffer.Dispose(); */ }
/// <summary> /// Tries to create a new instance of the <see cref="RIOBufferPool" />. /// </summary> /// <param name="rioHandle">The object that provides work with Winsock registered I/O extensions.</param> /// <param name="segmentLength">The length of the segment.</param> /// <param name="segmentsCount">The count of the segments.</param> /// <returns> /// An instance of <see cref="TryResult{T}" /> which encapsulates result of the operation. /// <see cref="TryResult{T}.Success" /> contains <c>true</c> if operation was successful, <c>false</c> otherwise. /// <see cref="TryResult{T}.Result" /> contains valid object if operation was successful, <c>null</c> otherwise. /// </returns> /// <remarks> /// The multiplication of <paramref name="segmentLength" /> and <paramref name="segmentsCount" /> must produce value that is aligned to Memory Allocation Granularity. /// </remarks> public static unsafe TryResult <RIOBufferPool> TryCreate(RIOHandle rioHandle, UInt32 segmentLength, UInt32 segmentsCount) { // calculate size of the memory buffer to allocate var bufferLength = segmentLength * segmentsCount; void *memoryPointer; IntPtr buffer; IntPtr bufferId; // 1 try allocate memory block { // try reserve and commit memory block memoryPointer = KernelInterop.VirtualAlloc(null, bufferLength, KernelInterop.MEM_COMMIT | KernelInterop.MEM_RESERVE, KernelInterop.PAGE_READWRITE); // check if allocation has failed if (memoryPointer == null) { // get kernel error code var kernelErrorCode = (KernelErrorCode)KernelInterop.GetLastError(); // return result return(TryResult <RIOBufferPool> .CreateFail(kernelErrorCode)); } // set buffer buffer = (IntPtr)memoryPointer; } // 2 try register buffer with Registered I/O extensions { bufferId = rioHandle.RegisterBuffer(buffer, bufferLength); if (bufferId == WinsockInterop.RIO_INVALID_BUFFERID) { // get winsock error code var winsockErrorCode = (WinsockErrorCode)WinsockInterop.WSAGetLastError(); // free allocated memory var freeResult = KernelInterop.VirtualFree(memoryPointer, 0, KernelInterop.MEM_RELEASE); // set kernel error code if (freeResult) { // return result return(TryResult <RIOBufferPool> .CreateFail(winsockErrorCode)); } // get kernel error code var kernelErrorCode = (KernelErrorCode)KernelInterop.GetLastError(); // return result return(TryResult <RIOBufferPool> .CreateFail(kernelErrorCode, winsockErrorCode)); } } // 3 success var result = new RIOBufferPool(buffer, bufferLength, bufferId, segmentLength, segmentsCount); // return result return(TryResult <RIOBufferPool> .CreateSuccess(result)); }