Ejemplo n.º 1
0
        public ParameterConstantBuffer(GraphicsDevice device, string constantBufferName, ShaderConstantBufferDescription constantBufferDesc)
        {
            ConstantBufferDesc = constantBufferDesc;
            constantBufferDatas = new ConstantBufferData[GraphicsDevice.ThreadCount];
            dataStreams = new DataPointer[GraphicsDevice.ThreadCount];

            for (uint i = 0; i < GraphicsDevice.ThreadCount; ++i)
            {
                constantBufferDatas[i] = new ConstantBufferData(constantBufferDesc);
                dataStreams[i] = new DataPointer(constantBufferDatas[i].Data, constantBufferDesc.Size);
            }

            Buffer = SiliconStudio.Paradox.Graphics.Buffer.New(device, constantBufferDatas[0].Desc.Size, BufferFlags.ConstantBuffer, UsingMap ? GraphicsResourceUsage.Dynamic : GraphicsResourceUsage.Default);
            
            // We want to clear flags
            // TODO: Should be later replaced with either an internal field on GraphicsResourceBase, or a reset counter somewhere?
            Buffer.Reload = Reload;
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Loads an image from an unmanaged memory pointer.
 /// </summary>
 /// <param name="dataBuffer">Pointer to an unmanaged memory. If <see cref="makeACopy"/> is false, this buffer must be allocated with <see cref="Utilities.AllocateMemory"/>.</param>
 /// <param name="makeACopy">True to copy the content of the buffer to a new allocated buffer, false otherwhise.</param>
 /// <returns>An new image.</returns>
 /// <remarks>If <see cref="makeACopy"/> is set to false, the returned image is now the holder of the unmanaged pointer and will release it on Dispose. </remarks>
 public static Image Load(DataPointer dataBuffer, bool makeACopy = false)
 {
     return Load(dataBuffer.Pointer, dataBuffer.Size, makeACopy);
 }
Ejemplo n.º 3
0
 /// <summary>
 /// Creates a new <see cref="Buffer" /> instance.
 /// </summary>
 /// <param name="device">The <see cref="GraphicsDevice"/>.</param>
 /// <param name="dataPointer">The data pointer.</param>
 /// <param name="elementSize">Size of the element.</param>
 /// <param name="bufferFlags">The buffer flags to specify the type of buffer.</param>
 /// <param name="usage">The usage.</param>
 /// <returns>An instance of a new <see cref="Buffer" /></returns>
 public static Buffer New(GraphicsDevice device, DataPointer dataPointer, int elementSize, BufferFlags bufferFlags, GraphicsResourceUsage usage = GraphicsResourceUsage.Default)
 {
     return(New(device, dataPointer, elementSize, bufferFlags, PixelFormat.None, usage));
 }
Ejemplo n.º 4
0
 /// <summary>
 /// Copies the content an array of data on CPU memory to this buffer into GPU memory.
 /// </summary>
 /// <param name="fromData">A data pointer.</param>
 /// <param name="offsetInBytes">The offset in bytes to write to.</param>
 /// <exception cref="System.ArgumentException"></exception>
 /// <remarks>
 /// This method is only working when called from the main thread that is accessing the main <see cref="GraphicsDevice"/>. See the unmanaged documentation about Map/UnMap for usage and restrictions.
 /// </remarks>
 public void SetData(DataPointer fromData, int offsetInBytes = 0)
 {
     SetData(GraphicsDevice, fromData, offsetInBytes);
 }
Ejemplo n.º 5
0
 /// <summary>
 /// Creates a new index buffer with <see cref="GraphicsResourceUsage.Immutable"/> uasge by default.
 /// </summary>
 /// <param name="device">The <see cref="GraphicsDevice"/>.</param>
 /// <param name="value">The value to initialize the index buffer.</param>
 /// <param name="usage">The usage of this resource.</param>
 /// <returns>A index buffer</returns>
 public static Buffer New(GraphicsDevice device, DataPointer value, GraphicsResourceUsage usage = GraphicsResourceUsage.Immutable)
 {
     return(Buffer.New(device, value, 0, BufferFlags.IndexBuffer, usage));
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Copies the content an data on CPU memory to this texture into GPU memory.
        /// </summary>
        /// <param name="device">The <see cref="GraphicsDevice"/>.</param>
        /// <param name="fromData">The data to copy from.</param>
        /// <param name="arraySlice">The array slice index. This value must be set to 0 for Texture 3D.</param>
        /// <param name="mipSlice">The mip slice index.</param>
        /// <param name="region">Destination region</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>
        /// See unmanaged documentation for usage and restrictions.
        /// </remarks>
        public unsafe void SetData(GraphicsDevice device, DataPointer fromData, int arraySlice = 0, int mipSlice = 0, ResourceRegion?region = null)
        {
            if (device == null)
            {
                throw new ArgumentNullException("device");
            }
            if (region.HasValue && this.Description.Usage != GraphicsResourceUsage.Default)
            {
                throw new ArgumentException("Region is only supported for textures with ResourceUsage.Default");
            }

            // Get mipmap description for the specified mipSlice
            var mipMapDesc = this.GetMipMapDescription(mipSlice);

            int width  = mipMapDesc.Width;
            int height = mipMapDesc.Height;
            int depth  = mipMapDesc.Depth;

            // If we are using a region, then check that parameters are fine
            if (region.HasValue)
            {
                int newWidth  = region.Value.Right - region.Value.Left;
                int newHeight = region.Value.Bottom - region.Value.Top;
                int newDepth  = region.Value.Back - region.Value.Front;
                if (newWidth > width)
                {
                    throw new ArgumentException(string.Format("Region width [{0}] cannot be greater than mipmap width [{1}]", newWidth, width), "region");
                }
                if (newHeight > height)
                {
                    throw new ArgumentException(string.Format("Region height [{0}] cannot be greater than mipmap height [{1}]", newHeight, height), "region");
                }
                if (newDepth > depth)
                {
                    throw new ArgumentException(string.Format("Region depth [{0}] cannot be greater than mipmap depth [{1}]", newDepth, depth), "region");
                }

                width  = newWidth;
                height = newHeight;
                depth  = newDepth;
            }

            // Size per pixel
            var sizePerElement = Description.Format.SizeInBytes();

            // Calculate depth stride based on mipmap level
            int rowStride;

            // Depth Stride
            int textureDepthStride;

            // Compute Actual pitch
            Image.ComputePitch(this.Description.Format, width, height, out rowStride, out textureDepthStride, out width, out height);

            // Size Of actual texture data
            int sizeOfTextureData = textureDepthStride * depth;

            // Check size validity of data to copy to
            if (fromData.Size != sizeOfTextureData)
            {
                throw new ArgumentException(string.Format("Size of toData ({0} bytes) is not compatible expected size ({1} bytes) : Width * Height * Depth * sizeof(PixelFormat) size in bytes", fromData.Size, sizeOfTextureData));
            }

            // Calculate the subResourceIndex for a Texture
            int subResourceIndex = this.GetSubResourceIndex(arraySlice, mipSlice);

            // If this texture is declared as default usage, we use UpdateSubresource that supports sub resource region.
            if (this.Description.Usage == GraphicsResourceUsage.Default)
            {
                // If using a specific region, we need to handle this case
                if (region.HasValue)
                {
                    var regionValue   = region.Value;
                    var sourceDataPtr = fromData.Pointer;

                    // Workaround when using region with a deferred context and a device that does not support CommandList natively
                    // see http://blogs.msdn.com/b/chuckw/archive/2010/07/28/known-issue-direct3d-11-updatesubresource-and-deferred-contexts.aspx
                    if (device.NeedWorkAroundForUpdateSubResource)
                    {
                        if (IsBlockCompressed)
                        {
                            regionValue.Left   /= 4;
                            regionValue.Right  /= 4;
                            regionValue.Top    /= 4;
                            regionValue.Bottom /= 4;
                        }
                        sourceDataPtr = new IntPtr((byte *)sourceDataPtr - (regionValue.Front * textureDepthStride) - (regionValue.Top * rowStride) - (regionValue.Left * sizePerElement));
                    }
                    device.UpdateSubresource(this, subResourceIndex, new DataBox(sourceDataPtr, rowStride, textureDepthStride), regionValue);
                }
                else
                {
                    device.UpdateSubresource(this, subResourceIndex, new DataBox(fromData.Pointer, rowStride, textureDepthStride));
                }
            }
            else
            {
                var mappedResource = device.MapSubresource(this, subResourceIndex, this.Description.Usage == GraphicsResourceUsage.Dynamic ? MapMode.WriteDiscard : MapMode.Write);
                var box            = mappedResource.DataBox;

                // If depth == 1 (Texture1D, Texture2D or TextureCube), then depthStride is not used
                var boxDepthStride = this.Description.Depth == 1 ? box.SlicePitch : textureDepthStride;

                // The fast way: If same stride, we can directly copy the whole texture in one shot
                if (box.RowPitch == rowStride && boxDepthStride == textureDepthStride)
                {
                    Utilities.CopyMemory(box.DataPointer, fromData.Pointer, sizeOfTextureData);
                }
                else
                {
                    // Otherwise, the long way by copying each scanline
                    var destPerDepthPtr = (byte *)box.DataPointer;
                    var sourcePtr       = (byte *)fromData.Pointer;

                    // Iterate on all depths
                    for (int j = 0; j < depth; j++)
                    {
                        var destPtr = destPerDepthPtr;
                        // Iterate on each line
                        for (int i = 0; i < height; i++)
                        {
                            Utilities.CopyMemory((IntPtr)destPtr, (IntPtr)sourcePtr, rowStride);
                            destPtr   += box.RowPitch;
                            sourcePtr += rowStride;
                        }
                        destPerDepthPtr += box.SlicePitch;
                    }
                }
                device.UnmapSubresource(mappedResource);
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Copies the content of this texture from GPU memory to a pointer on CPU memory using a specific staging resource.
        /// </summary>
        /// <param name="stagingTexture">The staging texture used to transfer the texture to.</param>
        /// <param name="toData">The pointer to data in CPU memory.</param>
        /// <param name="arraySlice">The array slice index. This value must be set to 0 for Texture 3D.</param>
        /// <param name="mipSlice">The mip slice index.</param>
        /// <param name="doNotWait">if set to <c>true</c> this method will return immediately if the resource is still being used by the GPU for writing. Default is false</param>
        /// <returns><c>true</c> if data was correctly retrieved, <c>false</c> if <see cref="doNotWait"/> flag was true and the resource is still being used by the GPU for writing.</returns>
        /// <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 unsafe bool GetData(Texture stagingTexture, DataPointer toData, int arraySlice = 0, int mipSlice = 0, bool doNotWait = false)
        {
            if (stagingTexture == null)
            {
                throw new ArgumentNullException("stagingTexture");
            }
            var device = GraphicsDevice;
            //var deviceContext = device.NativeDeviceContext;

            // Get mipmap description for the specified mipSlice
            var mipmap = this.GetMipMapDescription(mipSlice);

            // Copy height, depth
            int height = mipmap.HeightPacked;
            int depth  = mipmap.Depth;

            // Calculate depth stride based on mipmap level
            int rowStride = mipmap.RowStride;

            // Depth Stride
            int textureDepthStride = mipmap.DepthStride;

            // MipMap Stride
            int mipMapSize = mipmap.MipmapSize;

            // Check size validity of data to copy to
            if (toData.Size > mipMapSize)
            {
                throw new ArgumentException(string.Format("Size of toData ({0} bytes) is not compatible expected size ({1} bytes) : Width * Height * Depth * sizeof(PixelFormat) size in bytes", toData.Size, mipMapSize));
            }

            // Copy the actual content of the texture to the staging resource
            if (!ReferenceEquals(this, stagingTexture))
            {
                device.Copy(this, stagingTexture);
            }

            // Calculate the subResourceIndex for a Texture2D
            int subResourceIndex = this.GetSubResourceIndex(arraySlice, mipSlice);

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

            // Box can be empty if DoNotWait is set to true, return false if empty
            var box = mappedResource.DataBox;

            if (box.IsEmpty)
            {
                return(false);
            }

            // If depth == 1 (Texture1D, Texture2D or TextureCube), then depthStride is not used
            var boxDepthStride = this.Description.Depth == 1 ? box.SlicePitch : textureDepthStride;

            var isFlippedTexture = IsFlippedTexture();

            // The fast way: If same stride, we can directly copy the whole texture in one shot
            if (box.RowPitch == rowStride && boxDepthStride == textureDepthStride && !isFlippedTexture)
            {
                Utilities.CopyMemory(toData.Pointer, box.DataPointer, mipMapSize);
            }
            else
            {
                // Otherwise, the long way by copying each scanline
                var sourcePerDepthPtr = (byte *)box.DataPointer;
                var destPtr           = (byte *)toData.Pointer;

                // Iterate on all depths
                for (int j = 0; j < depth; j++)
                {
                    var sourcePtr = sourcePerDepthPtr;
                    // Iterate on each line

                    if (isFlippedTexture)
                    {
                        sourcePtr = sourcePtr + box.RowPitch * (height - 1);
                        for (int i = height - 1; i >= 0; i--)
                        {
                            // Copy a single row
                            Utilities.CopyMemory(new IntPtr(destPtr), new IntPtr(sourcePtr), rowStride);
                            sourcePtr -= box.RowPitch;
                            destPtr   += rowStride;
                        }
                    }
                    else
                    {
                        for (int i = 0; i < height; i++)
                        {
                            // Copy a single row
                            Utilities.CopyMemory(new IntPtr(destPtr), new IntPtr(sourcePtr), rowStride);
                            sourcePtr += box.RowPitch;
                            destPtr   += rowStride;
                        }
                    }
                    sourcePerDepthPtr += box.SlicePitch;
                }
            }

            // Make sure that we unmap the resource in case of an exception
            device.UnmapSubresource(mappedResource);

            return(true);
        }
Ejemplo n.º 8
0
 /// <summary>
 /// Copies the content an data on CPU memory to this texture into GPU memory using the specified <see cref="GraphicsDevice"/> (The graphics device could be deffered).
 /// </summary>
 /// <param name="fromData">The data to copy from.</param>
 /// <param name="arraySlice">The array slice index. This value must be set to 0 for Texture 3D.</param>
 /// <param name="mipSlice">The mip slice index.</param>
 /// <param name="region">Destination region</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 on the main graphics device. Use method with explicit graphics device to set data on a deferred context.
 /// See also unmanaged documentation about Map/UnMap for usage and restrictions.
 /// </remarks>
 public void SetData(DataPointer fromData, int arraySlice = 0, int mipSlice = 0, ResourceRegion?region = null)
 {
     SetData(GraphicsDevice, fromData, arraySlice, mipSlice, region);
 }
Ejemplo n.º 9
0
 /// <summary>
 /// Loads an image from an unmanaged memory pointer.
 /// </summary>
 /// <param name="dataBuffer">Pointer to an unmanaged memory. If <see cref="makeACopy"/> is false, this buffer must be allocated with <see cref="Utilities.AllocateMemory"/>.</param>
 /// <param name="makeACopy">True to copy the content of the buffer to a new allocated buffer, false otherwhise.</param>
 /// <returns>An new image.</returns>
 /// <remarks>If <see cref="makeACopy"/> is set to false, the returned image is now the holder of the unmanaged pointer and will release it on Dispose. </remarks>
 public static Image Load(DataPointer dataBuffer, bool makeACopy = false)
 {
     return Load(dataBuffer.Pointer, dataBuffer.Size, makeACopy);
 }
Ejemplo n.º 10
0
            /// <summary>
            /// Creates a new StructuredCounter buffer <see cref="GraphicsResourceUsage.Default" /> uasge.
            /// </summary>
            /// <param name="device">The <see cref="GraphicsDevice"/>.</param>
            /// <param name="value">The value to initialize the StructuredCounter buffer.</param>
            /// <param name="elementSize">Size of the element.</param>
            /// <returns>A StructuredCounter buffer</returns>
            public static Buffer New(GraphicsDevice device, DataPointer value, int elementSize)
            {
                const BufferFlags BufferFlags = BufferFlags.StructuredCounterBuffer | BufferFlags.ShaderResource | BufferFlags.UnorderedAccess;

                return(Buffer.New(device, value, elementSize, BufferFlags));
            }
Ejemplo n.º 11
0
 /// <summary>
 /// Creates a new constant buffer with <see cref="GraphicsResourceUsage.Dynamic"/> usage.
 /// </summary>
 /// <param name="device">The <see cref="GraphicsDevice"/>.</param>
 /// <param name="value">The value to initialize the constant buffer.</param>
 /// <param name="usage">The usage of this resource.</param>
 /// <returns>A constant buffer</returns>
 public static Buffer New(GraphicsDevice device, DataPointer value, GraphicsResourceUsage usage = GraphicsResourceUsage.Dynamic)
 {
     return(Buffer.New(device, value, 0, BufferFlags.ConstantBuffer, usage));
 }
Ejemplo n.º 12
0
 /// <summary>
 /// Creates a new Raw buffer with <see cref="GraphicsResourceUsage.Default"/> uasge by default.
 /// </summary>
 /// <param name="device">The <see cref="GraphicsDevice"/>.</param>
 /// <param name="value">The value to initialize the Raw buffer.</param>
 /// <param name="additionalBindings">The additional bindings (for example, to create a combined raw/index buffer, pass <see cref="BufferFlags.IndexBuffer" />)</param>
 /// <param name="usage">The usage of this resource.</param>
 /// <returns>A Raw buffer</returns>
 public static Buffer New(GraphicsDevice device, DataPointer value, BufferFlags additionalBindings = BufferFlags.None, GraphicsResourceUsage usage = GraphicsResourceUsage.Default)
 {
     return(Buffer.New(device, value, 0, BufferFlags.RawBuffer | additionalBindings, usage));
 }
Ejemplo n.º 13
0
 /// <summary>
 /// Creates a new Typed buffer <see cref="GraphicsResourceUsage.Default" /> uasge.
 /// </summary>
 /// <param name="device">The <see cref="GraphicsDevice"/>.</param>
 /// <param name="value">The value to initialize the Typed buffer.</param>
 /// <param name="viewFormat">The view format of the buffer.</param>
 /// <param name="isUnorderedAccess">if set to <c>true</c> this buffer supports unordered access (RW in HLSL).</param>
 /// <param name="usage">The usage of this resource.</param>
 /// <returns>A Typed buffer</returns>
 public static Buffer New(GraphicsDevice device, DataPointer value, PixelFormat viewFormat, bool isUnorderedAccess = false, GraphicsResourceUsage usage = GraphicsResourceUsage.Default)
 {
     return(Buffer.New(device, value, 0, BufferFlags.ShaderResource | (isUnorderedAccess?BufferFlags.UnorderedAccess : BufferFlags.None), viewFormat, usage));
 }
Ejemplo n.º 14
0
 /// <summary>
 /// Loads an image from an unmanaged memory pointer.
 /// </summary>
 /// <param name="dataBuffer">Pointer to an unmanaged memory. If <see cref="makeACopy"/> is false, this buffer must be allocated with <see cref="Utilities.AllocateMemory"/>.</param>
 /// <param name="makeACopy">True to copy the content of the buffer to a new allocated buffer, false otherwhise.</param>
 /// <param name="loadAsSRGB">Indicate if the image should be loaded as an sRGB texture</param>
 /// <returns>An new image.</returns>
 /// <remarks>If <see cref="makeACopy"/> is set to false, the returned image is now the holder of the unmanaged pointer and will release it on Dispose. </remarks>
 public static Image Load(DataPointer dataBuffer, bool makeACopy = false, bool loadAsSRGB = true)
 {
     return Load(dataBuffer.Pointer, dataBuffer.Size, makeACopy, loadAsSRGB);
 }