コード例 #1
0
        public MemoryAllocation GetMemoryFor(int requiredSizeInBytes, MemoryFlag flags, IntPtr data, int data_size_in_bytes = -1)
        {
            if (!IsInitialized())
            {
                return(null);
            }

            var accessFlags = flags & (MemoryFlag.ReadOnly | MemoryFlag.WriteOnly | MemoryFlag.ReadWrite);

            MemoryAllocation candidate        = null;
            uint             bestMatchingSize = uint.MaxValue;
            int itemToSwap = -1;

            for (int i = 0; i < freeMemoryAllocations.Count; i++)
            {
                var item = freeMemoryAllocations[i];
                if (item.flags == accessFlags && item.bufferSizeInBytes >= requiredSizeInBytes && item.bufferSizeInBytes < bestMatchingSize) //Select the smallest sufficient memory allocation from our allocations
                {
                    bestMatchingSize = item.bufferSizeInBytes;
                    candidate        = item;
                    itemToSwap       = i;
                    if (item.bufferSizeInBytes == requiredSizeInBytes)
                    {
                        break;
                    }
                }
            }

            if (candidate == null)
            {
                candidate = CreateMemoryAllocation(clContext, (uint)requiredSizeInBytes, accessFlags, IntPtr.Zero);
                usedMemoryAllocations.Add(candidate);
            }
            else
            {
                freeMemoryAllocations.RemoveAt(itemToSwap);
                usedMemoryAllocations.Add(candidate);
            }

            if (flags.HasFlag(MemoryFlag.CopyHostPointer) && data != IntPtr.Zero)
            {
                int upload_size_in_bytes = data_size_in_bytes >= 0 ? data_size_in_bytes : requiredSizeInBytes;

                IntPtr ev           = IntPtr.Zero;
                var    errCodeWrite = EnqueuedCommandsNativeApi.EnqueueWriteBuffer(commandQueue, candidate.buffer, 0U, UIntPtr.Zero, new UIntPtr((uint)upload_size_in_bytes), data, 0, null, out ev);
                ThrowOnError(errCodeWrite, String.Format("Failed to enqueue write buffer. Write-size:{0}, Target buffer size: {1}", requiredSizeInBytes, candidate.bufferSizeInBytes));

                var errCodeEv = EventsNativeApi.ReleaseEvent(ev);
                ThrowOnError(errCodeEv, String.Format("Failed release event (EnqueueWriteBuffer)"));
            }

            return(candidate);
        }