Exemplo n.º 1
0
        public BufferInfo(IMgThreadPartition partition, MgBufferUsageFlagBits usage, MgMemoryPropertyFlagBits propertyFlags, uint bufferSize)
        {
            Debug.Assert(partition != null);

            mDevice = partition.Device;
            Debug.Assert(mDevice != null);

            mUsageFlags = usage;

            mMemoryPropertyFlags = propertyFlags;

            var bufferCreateInfo = new MgBufferCreateInfo
            {
                Usage = usage,
                Size  = bufferSize,
            };

            IMgBuffer buffer;

            var device = partition.Device;

            var result = device.CreateBuffer(bufferCreateInfo, null, out buffer);

            Debug.Assert(result == Result.SUCCESS);

            MgMemoryRequirements memReqs;

            device.GetBufferMemoryRequirements(buffer, out memReqs);
            mAlignment  = memReqs.Alignment;
            mBufferSize = memReqs.Size;

            uint memoryTypeIndex;

            partition.GetMemoryType(memReqs.MemoryTypeBits, mMemoryPropertyFlags, out memoryTypeIndex);

            var memAlloc = new MgMemoryAllocateInfo
            {
                MemoryTypeIndex = memoryTypeIndex,
                AllocationSize  = memReqs.Size,
            };

            IMgDeviceMemory deviceMemory;

            result = device.AllocateMemory(memAlloc, null, out deviceMemory);
            Debug.Assert(result == Result.SUCCESS);

            buffer.BindBufferMemory(device, deviceMemory, 0);


            mBuffer       = buffer;
            mDeviceMemory = deviceMemory;

            mDescriptor = new MgDescriptorBufferInfo
            {
                Buffer = mBuffer,
                Offset = 0,
                Range  = mBufferSize,
            };
        }
Exemplo n.º 2
0
        public MgOptimizedStorage AllocateBlocks(MgStorageBufferInstance[] bufferInstances)
        {
            var memoryBlocks = new List <MgOptimizedStorageBlock>();

            foreach (var instance in bufferInstances)
            {
                var pAllocateInfo = new MgMemoryAllocateInfo
                {
                    AllocationSize  = instance.AllocationSize,
                    MemoryTypeIndex = instance.TypeIndex,
                };

                var err = mConfiguration.Device.AllocateMemory(pAllocateInfo,
                                                               null,
                                                               out IMgDeviceMemory pMemory);

                if (err != Result.SUCCESS)
                {
                    // START OVER
                    throw new InvalidOperationException(err.ToString());;
                }

                var children = new List <uint>();
                foreach (var mapping in instance.Mappings)
                {
                    children.Add(mapping.Index);
                }

                var block = new MgOptimizedStorageBlock
                {
                    Buffer              = instance.Buffer,
                    DeviceMemory        = pMemory,
                    AllocationSize      = instance.AllocationSize,
                    MemoryOffset        = 0UL,
                    Usage               = instance.Usage,
                    MemoryPropertyFlags = instance.MemoryPropertyFlags,
                    PackingOrder        = children.ToArray(),
                };

                block.Buffer.BindBufferMemory(
                    mConfiguration.Device,
                    block.DeviceMemory,
                    block.MemoryOffset);

                memoryBlocks.Add(block);
            }
            return(new MgOptimizedStorage(memoryBlocks.ToArray()));
        }
Exemplo n.º 3
0
        public GLDeviceMemory(MgMemoryAllocateInfo pAllocateInfo, IGLErrorHandler errHandler)
        {
            mErrHandler   = errHandler;
            mBufferType   = (GLMemoryBufferType)pAllocateInfo.MemoryTypeIndex;
            mIsHostCached = (mBufferType == GLMemoryBufferType.INDIRECT || mBufferType == GLMemoryBufferType.IMAGE);

            if (pAllocateInfo.AllocationSize > (ulong)int.MaxValue)
            {
                throw new ArgumentOutOfRangeException("pAllocateInfo.AllocationSize > int.MaxValue");
            }

            mBufferSize = (int)pAllocateInfo.AllocationSize;

            if (mBufferType != GLMemoryBufferType.IMAGE)
            {
                mBufferTarget = GetBufferTarget(mBufferType);
            }

            if (mIsHostCached || pAllocateInfo.MemoryTypeIndex == (uint)GLMemoryBufferType.IMAGE)
            {
                mHandle = Marshal.AllocHGlobal(mBufferSize);
            }
            else
            {
                if (mBufferTarget.HasValue)
                {
                    var buffers = new uint[1];
                    // ARB_direct_state_access
                    // Allows buffer objects to be initialised without binding them
                    GL.CreateBuffers(1, buffers);

                    mErrHandler.LogGLError("GL.CreateBuffers");
                    mBufferId = buffers[0];

                    // TODO : update flags based on buffer request
                    BufferStorageFlags flags = BufferStorageFlags.MapWriteBit | BufferStorageFlags.MapPersistentBit | BufferStorageFlags.MapCoherentBit;
                    GL.NamedBufferStorage(mBufferId, mBufferSize, IntPtr.Zero, flags);
                    mErrHandler.LogGLError("GL.NamedBufferStorage");

                    //					BufferAccessMask rangeFlags = BufferAccessMask.MapWriteBit | BufferAccessMask.MapPersistentBit | BufferAccessMask.MapCoherentBit;
                    //					Handle = GL.MapNamedBufferRange (buffers[0], (IntPtr)0, BufferSize, rangeFlags);
                }
            }
        }
Exemplo n.º 4
0
        public AmtDeviceMemory(IMTLDevice device, MgMemoryAllocateInfo pAllocateInfo)
        {
            if (pAllocateInfo == null)
            {
                throw new ArgumentNullException(nameof(pAllocateInfo));
            }

            if (pAllocateInfo.AllocationSize > nuint.MaxValue)
            {
                throw new ArgumentOutOfRangeException(nameof(pAllocateInfo.AllocationSize)
                                                      + " must be <= nuint.MaxValue");
            }

            AllocationSize = (nuint)pAllocateInfo.AllocationSize;

            var options = MTLResourceOptions.CpuCacheModeDefault;

            InternalBuffer = device.CreateBuffer(AllocationSize, options);
        }
Exemplo n.º 5
0
        void PrepareUniformBuffers()
        {
            var structSize = (uint)Marshal.SizeOf(typeof(UniformBufferObject));

            MgBufferCreateInfo bufferInfo = new MgBufferCreateInfo
            {
                Size  = structSize,
                Usage = MgBufferUsageFlagBits.UNIFORM_BUFFER_BIT,
            };

            var err = mConfiguration.Device.CreateBuffer(bufferInfo, null, out uniformDataVS.buffer);

            Debug.Assert(err == Result.SUCCESS);

            mConfiguration.Device.GetBufferMemoryRequirements(uniformDataVS.buffer, out MgMemoryRequirements memReqs);

            var isValid = mConfiguration.Partition.GetMemoryType(memReqs.MemoryTypeBits, MgMemoryPropertyFlagBits.HOST_VISIBLE_BIT | MgMemoryPropertyFlagBits.HOST_COHERENT_BIT, out uint typeIndex);

            Debug.Assert(isValid);

            MgMemoryAllocateInfo allocInfo = new MgMemoryAllocateInfo
            {
                AllocationSize  = memReqs.Size,
                MemoryTypeIndex = typeIndex,
            };

            err = mConfiguration.Device.AllocateMemory(allocInfo, null, out uniformDataVS.memory);
            Debug.Assert(err == Result.SUCCESS);

            err = uniformDataVS.buffer.BindBufferMemory(mConfiguration.Device, uniformDataVS.memory, 0);
            Debug.Assert(err == Result.SUCCESS);

            uniformDataVS.descriptor = new MgDescriptorBufferInfo
            {
                Buffer = uniformDataVS.buffer,
                Offset = 0,
                Range  = structSize,
            };

            UpdateUniformBuffers();
        }
Exemplo n.º 6
0
 public Result AllocateMemory(MgMemoryAllocateInfo pAllocateInfo, IMgAllocationCallbacks allocator, out IMgDeviceMemory pMemory)
 {
     pMemory = new AmtDeviceMemory(mDevice, pAllocateInfo);
     return(Result.SUCCESS);
 }
Exemplo n.º 7
0
 public Result AllocateMemory(MgMemoryAllocateInfo pAllocateInfo, IMgAllocationCallbacks allocator, out IMgDeviceMemory pMemory)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 8
0
 public Result AllocateMemory(MgMemoryAllocateInfo pAllocateInfo, IMgAllocationCallbacks allocator, out IMgDeviceMemory pMemory)
 {
     pMemory = mEntrypoint.DeviceMemory.CreateDeviceMemory(pAllocateInfo);
     return(Result.SUCCESS);
 }
Exemplo n.º 9
0
        void PrepareVertices()
        {
            TriangleVertex[] vertexBuffer =
            {
                new TriangleVertex {
                    position = new Vector3(1.0f, 1.0f, 0.0f),
                    color    = new Vector3(1.0f, 0.0f, 0.0f)
                },

                new TriangleVertex {
                    position = new Vector3(-1.0f, 1.0f, 0.0f),
                    color    = new Vector3(0.0f, 1.0f, 0.0f)
                },

                new TriangleVertex {
                    position = new Vector3(0.0f, -1.0f, 0.0f),
                    color    = new Vector3(0.0f, 0.0f, 1.0f)
                },
            };

            var structSize       = Marshal.SizeOf(typeof(TriangleVertex));
            var vertexBufferSize = (ulong)(vertexBuffer.Length * structSize);

            UInt32[] indexBuffer = { 0, 1, 2 };
            indices.count = (uint)indexBuffer.Length;
            var indexBufferSize = indices.count * sizeof(UInt32);

            var stagingBuffers = new
            {
                vertices = new StagingBuffer(),
                indices  = new StagingBuffer(),
            };

            {
                var vertexBufferInfo = new MgBufferCreateInfo
                {
                    Size  = vertexBufferSize,
                    Usage = MgBufferUsageFlagBits.TRANSFER_SRC_BIT,
                };

                var err = mConfiguration.Device.CreateBuffer(vertexBufferInfo, null, out stagingBuffers.vertices.buffer);
                Debug.Assert(err == Result.SUCCESS);

                mConfiguration.Device.GetBufferMemoryRequirements(stagingBuffers.vertices.buffer, out MgMemoryRequirements memReqs);

                var isValid = mConfiguration.Partition.GetMemoryType(memReqs.MemoryTypeBits,
                                                                     MgMemoryPropertyFlagBits.HOST_VISIBLE_BIT | MgMemoryPropertyFlagBits.HOST_COHERENT_BIT,
                                                                     out uint typeIndex);

                Debug.Assert(isValid);

                MgMemoryAllocateInfo memAlloc = new MgMemoryAllocateInfo
                {
                    AllocationSize  = memReqs.Size,
                    MemoryTypeIndex = typeIndex,
                };

                err = mConfiguration.Device.AllocateMemory(memAlloc, null, out stagingBuffers.vertices.memory);
                Debug.Assert(err == Result.SUCCESS);

                // Map and copy
                err = stagingBuffers.vertices.memory.MapMemory(mConfiguration.Device, 0, memAlloc.AllocationSize, 0, out IntPtr data);
                Debug.Assert(err == Result.SUCCESS);

                var offset = 0;
                foreach (var vertex in vertexBuffer)
                {
                    IntPtr dest = IntPtr.Add(data, offset);
                    Marshal.StructureToPtr(vertex, dest, false);
                    offset += structSize;
                }

                stagingBuffers.vertices.memory.UnmapMemory(mConfiguration.Device);

                stagingBuffers.vertices.buffer.BindBufferMemory(mConfiguration.Device, stagingBuffers.vertices.memory, 0);
                Debug.Assert(err == Result.SUCCESS);
            }

            {
                var vertexBufferInfo = new MgBufferCreateInfo
                {
                    Size  = vertexBufferSize,
                    Usage = MgBufferUsageFlagBits.VERTEX_BUFFER_BIT | MgBufferUsageFlagBits.TRANSFER_DST_BIT,
                };

                var err = mConfiguration.Device.CreateBuffer(vertexBufferInfo, null, out vertices.buffer);
                Debug.Assert(err == Result.SUCCESS);

                mConfiguration.Device.GetBufferMemoryRequirements(vertices.buffer, out MgMemoryRequirements memReqs);

                var isValid = mConfiguration.Partition.GetMemoryType(memReqs.MemoryTypeBits, MgMemoryPropertyFlagBits.DEVICE_LOCAL_BIT, out uint typeIndex);
                Debug.Assert(isValid);

                var memAlloc = new MgMemoryAllocateInfo
                {
                    AllocationSize  = memReqs.Size,
                    MemoryTypeIndex = typeIndex,
                };

                err = mConfiguration.Device.AllocateMemory(memAlloc, null, out vertices.memory);
                Debug.Assert(err == Result.SUCCESS);

                err = vertices.buffer.BindBufferMemory(mConfiguration.Device, vertices.memory, 0);
                Debug.Assert(err == Result.SUCCESS);
            }

            {
                var indexbufferInfo = new MgBufferCreateInfo
                {
                    Size  = indexBufferSize,
                    Usage = MgBufferUsageFlagBits.TRANSFER_SRC_BIT,
                };

                var err = mConfiguration.Device.CreateBuffer(indexbufferInfo, null, out stagingBuffers.indices.buffer);
                Debug.Assert(err == Result.SUCCESS);

                mConfiguration.Device.GetBufferMemoryRequirements(stagingBuffers.indices.buffer, out MgMemoryRequirements memReqs);

                var isValid = mConfiguration.Partition.GetMemoryType(memReqs.MemoryTypeBits,
                                                                     MgMemoryPropertyFlagBits.HOST_VISIBLE_BIT | MgMemoryPropertyFlagBits.HOST_COHERENT_BIT,
                                                                     out uint typeIndex);
                Debug.Assert(isValid);

                var memAlloc = new MgMemoryAllocateInfo
                {
                    AllocationSize  = memReqs.Size,
                    MemoryTypeIndex = typeIndex,
                };

                err = mConfiguration.Device.AllocateMemory(memAlloc, null, out stagingBuffers.indices.memory);
                Debug.Assert(err == Result.SUCCESS);

                err = stagingBuffers.indices.memory.MapMemory(mConfiguration.Device, 0, indexBufferSize, 0, out IntPtr data);
                Debug.Assert(err == Result.SUCCESS);

                var uintBuffer = new byte[indexBufferSize];

                var bufferSize = (int)indexBufferSize;
                Buffer.BlockCopy(indexBuffer, 0, uintBuffer, 0, bufferSize);
                Marshal.Copy(uintBuffer, 0, data, bufferSize);

                stagingBuffers.indices.memory.UnmapMemory(mConfiguration.Device);

                err = stagingBuffers.indices.buffer.BindBufferMemory(mConfiguration.Device, stagingBuffers.indices.memory, 0);
                Debug.Assert(err == Result.SUCCESS);
            }

            {
                var indexbufferInfo = new MgBufferCreateInfo
                {
                    Size  = indexBufferSize,
                    Usage = MgBufferUsageFlagBits.INDEX_BUFFER_BIT | MgBufferUsageFlagBits.TRANSFER_DST_BIT,
                };

                var err = mConfiguration.Device.CreateBuffer(indexbufferInfo, null, out indices.buffer);
                Debug.Assert(err == Result.SUCCESS);

                mConfiguration.Device.GetBufferMemoryRequirements(indices.buffer, out MgMemoryRequirements memReqs);

                var isValid = mConfiguration.Partition.GetMemoryType(memReqs.MemoryTypeBits, MgMemoryPropertyFlagBits.DEVICE_LOCAL_BIT, out uint typeIndex);
                Debug.Assert(isValid);

                var memAlloc = new MgMemoryAllocateInfo
                {
                    AllocationSize  = memReqs.Size,
                    MemoryTypeIndex = typeIndex,
                };

                err = mConfiguration.Device.AllocateMemory(memAlloc, null, out indices.memory);
                Debug.Assert(err == Result.SUCCESS);

                err = indices.buffer.BindBufferMemory(mConfiguration.Device, indices.memory, 0);
                Debug.Assert(err == Result.SUCCESS);
            }

            {
                var cmdBufferBeginInfo = new MgCommandBufferBeginInfo
                {
                };

                IMgCommandBuffer copyCmd = getCommandBuffer(true);

                copyCmd.CmdCopyBuffer(
                    stagingBuffers.vertices.buffer,
                    vertices.buffer,
                    new[]
                {
                    new MgBufferCopy
                    {
                        Size = vertexBufferSize,
                    }
                }
                    );

                copyCmd.CmdCopyBuffer(stagingBuffers.indices.buffer, indices.buffer,
                                      new[]
                {
                    new MgBufferCopy
                    {
                        Size = indexBufferSize,
                    }
                });

                flushCommandBuffer(copyCmd);

                stagingBuffers.vertices.buffer.DestroyBuffer(mConfiguration.Device, null);
                stagingBuffers.vertices.memory.FreeMemory(mConfiguration.Device, null);
                stagingBuffers.indices.buffer.DestroyBuffer(mConfiguration.Device, null);
                stagingBuffers.indices.memory.FreeMemory(mConfiguration.Device, null);
            }

            const uint VERTEX_BUFFER_BIND_ID = 0;

            vertices.inputBinding = new MgVertexInputBindingDescription
            {
                Binding   = VERTEX_BUFFER_BIND_ID,
                Stride    = (uint)structSize,
                InputRate = MgVertexInputRate.VERTEX,
            };

            var vertexSize = (uint)Marshal.SizeOf(typeof(Vector3));

            vertices.inputAttributes = new MgVertexInputAttributeDescription[]
            {
                new MgVertexInputAttributeDescription
                {
                    Binding  = VERTEX_BUFFER_BIND_ID,
                    Location = 0,
                    Format   = MgFormat.R32G32B32_SFLOAT,
                    Offset   = 0,
                },
                new MgVertexInputAttributeDescription
                {
                    Binding  = VERTEX_BUFFER_BIND_ID,
                    Location = 1,
                    Format   = MgFormat.R32G32B32_SFLOAT,
                    Offset   = vertexSize,
                }
            };

            vertices.inputState = new MgPipelineVertexInputStateCreateInfo
            {
                VertexBindingDescriptions = new MgVertexInputBindingDescription[]
                {
                    vertices.inputBinding,
                },
                VertexAttributeDescriptions = vertices.inputAttributes,
            };
        }
Exemplo n.º 10
0
 public IGLDeviceMemory CreateDeviceMemory(MgMemoryAllocateInfo createInfo)
 {
     return(new GLDeviceMemory(createInfo, mErrHandler));
 }
Exemplo n.º 11
0
        // Allocate one region of memory for the uniform buffer
        private void InitializeUniforms()
        {
            MgBufferCreateInfo pCreateInfo = new MgBufferCreateInfo
            {
                Usage = MgBufferUsageFlagBits.UNIFORM_BUFFER_BIT,
                Size  = MaxBytesPerFrame,
            };
            IMgBuffer buffer;
            var       err = mConfiguration.Device.CreateBuffer(pCreateInfo, null, out buffer);

            Debug.Assert(err == Result.SUCCESS);
            //dynamicConstantBuffer = device.CreateBuffer(MaxBytesPerFrame, (MTLResourceOptions)0);
            //dynamicConstantBuffer.Label = "UniformBuffer";

            MgMemoryRequirements uniformsMemReqs;

            mConfiguration.Device.GetBufferMemoryRequirements(buffer, out uniformsMemReqs);

            const MgMemoryPropertyFlagBits uniformPropertyFlags = MgMemoryPropertyFlagBits.HOST_COHERENT_BIT;

            uint uniformMemoryTypeIndex;

            mConfiguration.Partition.GetMemoryType(
                uniformsMemReqs.MemoryTypeBits, uniformPropertyFlags, out uniformMemoryTypeIndex);

            var uniformMemAlloc = new MgMemoryAllocateInfo
            {
                MemoryTypeIndex = uniformMemoryTypeIndex,
                AllocationSize  = uniformsMemReqs.Size,
            };

            IMgDeviceMemory deviceMemory;
            var             result = mConfiguration.Device.AllocateMemory(uniformMemAlloc, null, out deviceMemory);

            Debug.Assert(result == Result.SUCCESS);

            buffer.BindBufferMemory(mConfiguration.Device, deviceMemory, 0);

            mUniforms = new BufferInfo
            {
                Buffer       = buffer,
                DeviceMemory = deviceMemory,
                Offset       = 0,
                Length       = MaxBytesPerFrame,
            };

            IMgDescriptorSetLayout pSetLayout;
            var dslCreateInfo = new MgDescriptorSetLayoutCreateInfo
            {
                Bindings = new MgDescriptorSetLayoutBinding[]
                {
                    new MgDescriptorSetLayoutBinding
                    {
                        Binding         = 0,
                        DescriptorCount = 1,
                        DescriptorType  = MgDescriptorType.UNIFORM_BUFFER_DYNAMIC,
                        StageFlags      = MgShaderStageFlagBits.VERTEX_BIT,
                    },
                },
            };

            err = mConfiguration.Device.CreateDescriptorSetLayout(dslCreateInfo, null, out pSetLayout);

            var poolCreateInfo = new Magnesium.MgDescriptorPoolCreateInfo
            {
                MaxSets   = 1,
                PoolSizes = new MgDescriptorPoolSize[] {
                    new MgDescriptorPoolSize
                    {
                        DescriptorCount = 1,
                        Type            = MgDescriptorType.COMBINED_IMAGE_SAMPLER,
                    },
                },
            };

            err = mConfiguration.Device.CreateDescriptorPool(poolCreateInfo, null, out mDescriptorPool);

            IMgDescriptorSet[]          dSets;
            MgDescriptorSetAllocateInfo pAllocateInfo = new MgDescriptorSetAllocateInfo
            {
                DescriptorPool     = mDescriptorPool,
                DescriptorSetCount = 1,
                SetLayouts         = new IMgDescriptorSetLayout[]
                {
                    pSetLayout,
                },
            };

            mConfiguration.Device.AllocateDescriptorSets(pAllocateInfo, out dSets);
            mUniformDescriptorSet = dSets[0];

            MgWriteDescriptorSet[] writes = new MgWriteDescriptorSet[]
            {
                new MgWriteDescriptorSet
                {
                    DescriptorCount = 1,
                    DescriptorType  = MgDescriptorType.UNIFORM_BUFFER_DYNAMIC,
                    DstSet          = mUniformDescriptorSet,
                    BufferInfo      = new MgDescriptorBufferInfo[]
                    {
                        new MgDescriptorBufferInfo
                        {
                            Buffer = mUniforms.Buffer,
                            Offset = mUniforms.Offset,
                            Range  = mUniforms.Length,
                        },
                    },
                    DstBinding = 0,
                }
            };
            mConfiguration.Device.UpdateDescriptorSets(writes, null);


            mSetLayout = pSetLayout;
        }
Exemplo n.º 12
0
        void InitializeMesh()
        {
            // Generate meshes
            // Mg : Buffer

            var indicesInBytes  = (ulong)(sizeof(uint) * indicesVboData.Length);
            var vertexStride    = Marshal.SizeOf(typeof(Vector3));
            var verticesInBytes = (ulong)(vertexStride * positionVboData.Length);
            var bufferSize      = indicesInBytes + verticesInBytes;

            var bufferCreateInfo = new MgBufferCreateInfo
            {
                Usage = MgBufferUsageFlagBits.INDEX_BUFFER_BIT | MgBufferUsageFlagBits.VERTEX_BUFFER_BIT,
                Size  = bufferSize,
            };

            var device = mConfiguration.Device;

            var result = device.CreateBuffer(bufferCreateInfo, null, out mBuffer);

            Debug.Assert(result == Result.SUCCESS);

            MgMemoryRequirements memReqs;

            device.GetBufferMemoryRequirements(mBuffer, out memReqs);

            const MgMemoryPropertyFlagBits memoryPropertyFlags = MgMemoryPropertyFlagBits.HOST_COHERENT_BIT;

            uint memoryTypeIndex;

            mConfiguration.Partition.GetMemoryType(
                memReqs.MemoryTypeBits, memoryPropertyFlags, out memoryTypeIndex);

            var memAlloc = new MgMemoryAllocateInfo
            {
                MemoryTypeIndex = memoryTypeIndex,
                AllocationSize  = memReqs.Size,
            };

            result = device.AllocateMemory(memAlloc, null, out mDeviceMemory);
            Debug.Assert(result == Result.SUCCESS);

            mBuffer.BindBufferMemory(device, mDeviceMemory, 0);

            // COPY INDEX DATA
            IntPtr dest;

            result = mDeviceMemory.MapMemory(device, 0, bufferSize, 0, out dest);
            Debug.Assert(result == Result.SUCCESS);

            var tempIndices = new byte[indicesInBytes];

            Buffer.BlockCopy(indicesVboData, 0, tempIndices, 0, (int)indicesInBytes);

            Marshal.Copy(tempIndices, 0, dest, (int)indicesInBytes);

            // COPY VERTEX DATA

            var vertexOffset = indicesInBytes;

            // Copy the struct to unmanaged memory.
            int offset = (int)vertexOffset;

            for (int i = 0; i < positionVboData.Length; ++i)
            {
                IntPtr localDest = IntPtr.Add(dest, offset);
                Marshal.StructureToPtr(positionVboData[i], localDest, false);
                offset += vertexStride;
            }

            mDeviceMemory.UnmapMemory(device);

            mIndices = new BufferInfo
            {
                Buffer       = mBuffer,
                DeviceMemory = mDeviceMemory,
                Offset       = 0,
                Length       = indicesInBytes,
            };

            mVertices = new BufferInfo
            {
                Buffer       = mBuffer,
                DeviceMemory = mDeviceMemory,
                Offset       = indicesInBytes,
                Length       = verticesInBytes,
            };
        }