public void Copy(GraphicsResource source, GraphicsResource destination)
        {
            var sourceTexture      = source as Texture;
            var destinationTexture = destination as Texture;

            if (sourceTexture != null && destinationTexture != null)
            {
                var sourceParent      = sourceTexture.ParentTexture ?? sourceTexture;
                var destinationParent = destinationTexture.ParentTexture ?? destinationTexture;

                if (sourceParent.NativeResourceState != ResourceStates.CopySource)
                {
                    NativeCommandList.ResourceBarrierTransition(sourceTexture.NativeResource, sourceParent.NativeResourceState, ResourceStates.CopySource);
                }
                if (destinationParent.NativeResourceState != ResourceStates.CopyDestination)
                {
                    NativeCommandList.ResourceBarrierTransition(destinationTexture.NativeResource, destinationParent.NativeResourceState, ResourceStates.CopyDestination);
                }

                if (destinationTexture.Usage == GraphicsResourceUsage.Staging)
                {
                    int copyOffset = 0;
                    for (int arraySlice = 0; arraySlice < sourceParent.ArraySize; ++arraySlice)
                    {
                        for (int mipLevel = 0; mipLevel < sourceParent.MipLevels; ++mipLevel)
                        {
                            NativeCommandList.CopyTextureRegion(new TextureCopyLocation(destinationTexture.NativeResource,
                                                                                        new PlacedSubResourceFootprint
                            {
                                Footprint =
                                {
                                    Width    = Texture.CalculateMipSize(destinationTexture.Width,  mipLevel),
                                    Height   = Texture.CalculateMipSize(destinationTexture.Height, mipLevel),
                                    Depth    = Texture.CalculateMipSize(destinationTexture.Depth,  mipLevel),
                                    Format   = (SharpDX.DXGI.Format)destinationTexture.Format,
                                    RowPitch = destinationTexture.ComputeRowPitch(mipLevel),
                                },
                                Offset = copyOffset,
                            }), 0, 0, 0, new TextureCopyLocation(sourceTexture.NativeResource, arraySlice * sourceParent.MipLevels + mipLevel), null);

                            copyOffset += destinationTexture.ComputeSubresourceSize(mipLevel);
                        }
                    }

                    // Set a value that will
                    destinationParent.StagingFenceValue = GraphicsDevice.NextFenceValue;
                }
                else
                {
                    NativeCommandList.CopyResource(destinationTexture.NativeResource, sourceTexture.NativeResource);
                }

                if (sourceParent.NativeResourceState != ResourceStates.CopySource)
                {
                    NativeCommandList.ResourceBarrierTransition(sourceTexture.NativeResource, ResourceStates.CopySource, sourceParent.NativeResourceState);
                }
                if (destinationParent.NativeResourceState != ResourceStates.CopyDestination)
                {
                    NativeCommandList.ResourceBarrierTransition(destinationTexture.NativeResource, ResourceStates.CopyDestination, destinationParent.NativeResourceState);
                }
            }
            else
            {
                throw new NotImplementedException();
            }
        }