Example #1
0
        /// <summary>
        /// Copies the content an array of data on CPU memory to this buffer into GPU memory.
        /// </summary>
        /// <param name="device">The <see cref="GraphicsDevice"/>.</param>
        /// <param name="fromData">A data pointer.</param>
        /// <param name="offsetInBytes">The offset in bytes to write to.</param>
        /// <exception cref="System.ArgumentException"></exception>
        /// <remarks>
        /// See the unmanaged documentation about Map/UnMap for usage and restrictions.
        /// </remarks>
        public void SetData(CommandList commandList, DataPointer fromData, int offsetInBytes = 0)
        {
            // Check size validity of data to copy to
            if (fromData.Size > this.Description.SizeInBytes)
            {
                throw new ArgumentException("Size of data to upload larger than size of buffer");
            }

            // If this texture is declared as default usage, we can only use UpdateSubresource, which is not optimal but better than nothing
            if (this.Description.Usage == GraphicsResourceUsage.Default)
            {
                // Setup the dest region inside the buffer
                if ((this.Description.BufferFlags & BufferFlags.ConstantBuffer) != 0)
                {
                    commandList.UpdateSubresource(this, 0, new DataBox(fromData.Pointer, 0, 0));
                }
                else
                {
                    var destRegion = new ResourceRegion(offsetInBytes, 0, 0, offsetInBytes + fromData.Size, 1, 1);
                    commandList.UpdateSubresource(this, 0, new DataBox(fromData.Pointer, 0, 0), destRegion);
                }
            }
            else
            {
                if (offsetInBytes > 0)
                {
                    throw new ArgumentException("offset is only supported for textured declared with ResourceUsage.Default", "offsetInBytes");
                }

                var mappedResource = commandList.MapSubresource(this, 0, Usage == GraphicsResourceUsage.Staging ? MapMode.Write : MapMode.WriteDiscard);
                Utilities.CopyMemory(mappedResource.DataBox.DataPointer, fromData.Pointer, fromData.Size);
                commandList.UnmapSubresource(mappedResource);
            }
        }
Example #2
0
 public void Unmap()
 {
     if (UseBufferOffsets && mappedConstantBuffer.Resource != null)
     {
         using (new DefaultCommandListLock(commandList))
         {
             commandList.UnmapSubresource(mappedConstantBuffer);
             mappedConstantBuffer = new MappedResource();
         }
     }
 }
Example #3
0
        public void Unmap()
        {
#pragma warning disable 162
            if (UseBufferOffsets && mappedConstantBuffer.Resource != null)
            {
                using (new DefaultCommandListLock(commandList))
                {
                    commandList.UnmapSubresource(mappedConstantBuffer);
                    mappedConstantBuffer = new MappedResource();
                }
            }
#pragma warning restore 162
        }
Example #4
0
        public void Apply(CommandList commandList, ResourceGroup[] resourceGroups, int resourceGroupsOffset)
        {
            if (resourceGroupBindings.Length == 0)
            {
                return;
            }

            var resourceGroupBinding = Interop.Pin(ref resourceGroupBindings[0]);

            for (int i = 0; i < resourceGroupBindings.Length; i++, resourceGroupBinding = Interop.IncrementPinned(resourceGroupBinding))
            {
                var resourceGroup = resourceGroups[resourceGroupsOffset + i];

                // Upload cbuffer (if not done yet)
                if (resourceGroupBinding.ConstantBufferSlot != -1 && resourceGroup != null && resourceGroup.ConstantBuffer.Data != IntPtr.Zero)
                {
                    var  preallocatedBuffer = resourceGroup.ConstantBuffer.Buffer;
                    bool needUpdate         = true;
                    if (preallocatedBuffer == null)
                    {
                        preallocatedBuffer = resourceGroupBinding.ConstantBufferPreallocated; // If it's preallocated buffer, we always upload
                    }
                    else if (resourceGroup.ConstantBuffer.Uploaded)
                    {
                        needUpdate = false; // If it's not preallocated and already uploaded, we can avoid uploading it again
                    }
                    else
                    {
                        resourceGroup.ConstantBuffer.Uploaded = true; // First time it is uploaded
                    }
                    if (needUpdate)
                    {
                        if (hasResourceRenaming)
                        {
                            var mappedConstantBuffer = commandList.MapSubresource(preallocatedBuffer, 0, MapMode.WriteDiscard);
                            Utilities.CopyMemory(mappedConstantBuffer.DataBox.DataPointer, resourceGroup.ConstantBuffer.Data, resourceGroup.ConstantBuffer.Size);
                            commandList.UnmapSubresource(mappedConstantBuffer);
                        }
                        else
                        {
                            commandList.UpdateSubresource(preallocatedBuffer, 0, new DataBox(resourceGroup.ConstantBuffer.Data, resourceGroup.ConstantBuffer.Size, 0));
                        }
                    }

                    resourceGroup.DescriptorSet.SetConstantBuffer(resourceGroupBinding.ConstantBufferSlot, preallocatedBuffer, resourceGroup.ConstantBuffer.Offset, resourceGroup.ConstantBuffer.Size);
                }
            }
        }
Example #5
0
        /// <summary>
        /// Copies the content of this buffer from GPU memory to a CPU memory using a specific staging resource.
        /// </summary>
        /// <param name="stagingTexture">The staging buffer used to transfer the buffer.</param>
        /// <param name="toData">To data pointer.</param>
        /// <exception cref="System.ArgumentException">When strides is different from optimal strides, and TData is not the same size as the pixel format, or Width * Height != toData.Length</exception>
        /// <remarks>
        /// This method is only working when called from the main thread that is accessing the main <see cref="GraphicsDevice"/>.
        /// </remarks>
        public void GetData(CommandList commandList, Buffer stagingTexture, DataPointer toData)
        {
            // Check size validity of data to copy to
            if (toData.Size > this.Description.SizeInBytes)
            {
                throw new ArgumentException("Length of TData is larger than size of buffer");
            }

            // Copy the texture to a staging resource
            if (!ReferenceEquals(this, stagingTexture))
            {
                commandList.Copy(this, stagingTexture);
            }

            // Map the staging resource to a CPU accessible memory
            var mappedResource = commandList.MapSubresource(stagingTexture, 0, MapMode.Read);

            Utilities.CopyMemory(toData.Pointer, mappedResource.DataBox.DataPointer, toData.Size);
            // Make sure that we unmap the resource in case of an exception
            commandList.UnmapSubresource(mappedResource);
        }