예제 #1
0
 /// <summary>
 /// Function to lock a CPU accessible texture sub resource for reading/writing.
 /// </summary>
 /// <param name="lockFlags">Flags used to lock.</param>
 /// <param name="arrayIndex">[Optional] Array index of the sub resource to lock.</param>
 /// <param name="mipLevel">[Optional] The mip-map level of the sub resource to lock.</param>
 /// <param name="deferred">[Optional] The deferred graphics context used to lock the texture.</param>
 /// <returns>A stream used to write to the texture.</returns>
 /// <remarks>This method is used to lock down a sub resource in the texture for reading/writing. When locking a texture, the entire texture sub resource is locked and returned.  There is no setting to return a portion of the texture subresource.
 /// <para>This method is only available to textures created with a staging or dynamic usage setting.  Otherwise an exception will be raised.</para>
 /// <para>Only the Write, Discard (with the Write flag) and Read flags may be used in the <paramref name="lockFlags"/> parameter.  The Read flag can only be used with staging textures and is mutually exclusive.</para>
 /// <para>If the <paramref name="deferred"/> parameter is NULL (Nothing in VB.Net), then the immediate context is used.  Use a deferred context to allow multiple threads to lock the
 /// texture at the same time.</para>
 /// </remarks>
 /// <returns>This method will return a <see cref="GorgonLibrary.Graphics.GorgonTextureLockData">GorgonTextureLockData</see> object containing information about the locked sub resource as well as
 /// a <see cref="GorgonLibrary.IO.GorgonDataStream">GorgonDataStream</see> that is used to access the locked sub resource data.</returns>
 /// <exception cref="System.ArgumentException">Thrown when the texture is not a dynamic or staging texture.
 /// <para>-or-</para>
 /// <para>Thrown when the texture is not a staging texture and the Read flag has been specified.</para>
 /// <para>-or-</para>
 /// <para>Thrown when the texture is not a dynamic texture and the discard flag has been specified.</para>
 /// </exception>
 /// <exception cref="System.ArgumentOutOfRangeException">Thrown when the <paramref name="arrayIndex"/> or the <paramref name="mipLevel"/> parameters are less than 0, or larger than their respective counts in the texture settings.</exception>
 public virtual GorgonTextureLockData Lock(BufferLockFlags lockFlags,
                                           int arrayIndex          = 0,
                                           int mipLevel            = 0,
                                           GorgonGraphics deferred = null)
 {
     return(OnLock(lockFlags, arrayIndex, mipLevel, deferred));
 }
예제 #2
0
 public override GorgonTextureLockData Lock(BufferLockFlags lockFlags,
                                            int arrayIndex          = 0,
                                            int mipLevel            = 0,
                                            GorgonGraphics deferred = null)
 {
     throw new NotSupportedException(Resources.GORGFX_DEPTH_OPERATION_NOT_SUPPORTED);
 }
예제 #3
0
        /// <summary>
        /// Function used to lock the underlying buffer for reading/writing.
        /// </summary>
        /// <param name="lockFlags">Flags used when locking the buffer.</param>
        /// <param name="context">A graphics context to use when locking the buffer.</param>
        /// <returns>
        /// A data stream containing the buffer data.
        /// </returns>
        /// <exception cref="System.ArgumentException">
        /// lockFlags
        /// or
        /// lockFlags
        /// </exception>
        /// <remarks>
        /// Use the <paramref name="context" /> parameter to determine the context in which the buffer should be updated. This is necessary to use that context
        /// to update the buffer because 2 threads may not access the same resource at the same time.
        /// </remarks>
        protected override GorgonDataStream OnLock(BufferLockFlags lockFlags, GorgonGraphics context)
        {
            DX.DataStream lockStream;

            context.Context.MapSubresource(D3DBuffer, GetMapMode(lockFlags), D3D11.MapFlags.None, out lockStream);

            return(new GorgonDataStream(lockStream.DataPointer, (int)lockStream.Length));
        }
예제 #4
0
        /// <summary>
        /// Function used to lock the underlying buffer for reading/writing.
        /// </summary>
        /// <param name="lockFlags">Flags used when locking the buffer.</param>
        /// <param name="context">A graphics context to use when locking the buffer.</param>
        /// <returns>A data stream containing the buffer data.</returns>
        /// <remarks>
        /// Use the <paramref name="context"/> parameter to determine the context in which the buffer should be updated. This is necessary to use that context
        /// to update the buffer because 2 threads may not access the same resource at the same time.
        /// </remarks>
        protected virtual GorgonDataStream OnLock(BufferLockFlags lockFlags, GorgonGraphics context)
        {
#if DEBUG
            if ((lockFlags & BufferLockFlags.NoOverwrite) == BufferLockFlags.NoOverwrite)
            {
                throw new ArgumentException(Resources.GORGFX_BUFFER_NO_OVERWRITE_NOT_VALID, "lockFlags");
            }
#endif
            DX.DataStream lockStream;

            context.Context.MapSubresource(D3DBuffer, GetMapMode(lockFlags), D3D.MapFlags.None, out lockStream);

            return(new GorgonDataStream(lockStream.DataPointer, (int)lockStream.Length));
        }
예제 #5
0
        /// <summary>
        /// Function to retrieve the mapping mode for locking a buffer.
        /// </summary>
        /// <param name="flags">Flags to use when locking.</param>
        /// <returns>The D3D mapping mode.</returns>
        internal static D3D.MapMode GetMapMode(BufferLockFlags flags)
        {
            if ((flags & BufferLockFlags.Read) == BufferLockFlags.Read)
            {
                return((flags & BufferLockFlags.Write) == BufferLockFlags.Write ? D3D.MapMode.ReadWrite : D3D.MapMode.Read);
            }

            if ((flags & BufferLockFlags.Discard) == BufferLockFlags.Discard)
            {
                return(D3D.MapMode.WriteDiscard);
            }

            return((flags & BufferLockFlags.NoOverwrite) == BufferLockFlags.NoOverwrite
                                ? D3D.MapMode.WriteNoOverwrite
                                : D3D.MapMode.Write);
        }
예제 #6
0
        /// <summary>
        /// Function to lock a sub resource.
        /// </summary>
        /// <param name="lockFlags">Flags used to lock the data.</param>
        /// <param name="mipLevel">Mip map level to lock.</param>
        /// <param name="arrayIndex">Array index to lock (1D/2D textures only).</param>
        /// <param name="context">Graphics context to use for the lock.</param>
        /// <returns>The locking data.</returns>
        public GorgonTextureLockData Lock(BufferLockFlags lockFlags, int mipLevel, int arrayIndex, GorgonGraphics context)
        {
            lock (_syncLock)
            {
                var key = new LockCacheKey(context, mipLevel, arrayIndex);
                GorgonTextureLockData result;

                if (_locks.TryGetValue(key, out result))
                {
                    return(result);
                }

                switch (_texture.ResourceType)
                {
                case ResourceType.Texture1D:
                case ResourceType.Texture2D:
                case ResourceType.Texture3D:
                    DX.DataStream lockStream;

                    DX.DataBox box = context.Context.MapSubresource(_texture.D3DResource,
                                                                    D3D.Resource.CalculateSubResourceIndex(mipLevel, arrayIndex, _texture.Settings.MipCount),
                                                                    GetMapMode(lockFlags),
                                                                    D3D.MapFlags.None,
                                                                    out lockStream);

                    result = new GorgonTextureLockData(context, _texture, this, box, mipLevel, arrayIndex);

                    _locks.Add(key, result);
                    break;

                default:
                    throw new GorgonException(GorgonResult.CannotCreate,
                                              string.Format(Resources.GORGFX_RESOURCE_INVALID, _texture.ResourceType));
                }

                return(result);
            }
        }
예제 #7
0
        /// <summary>
        /// Function to lock the buffer for reading/writing.
        /// </summary>
        /// <param name="lockFlags">The flags to use when locking the buffer.</param>
        /// <param name="deferred">[Optional] A deferred context to use when locking the buffer.</param>
        /// <returns>A data stream pointing to the memory used by the buffer.</returns>
        /// <remarks>A data stream locked with this method does not have to be disposed of.  After it is <see cref="GorgonLibrary.Graphics.GorgonBaseBuffer.Unlock">unlocked</see>, the memory pointed
        /// at by the stream will be considered invalid.  However, for the sake of following practice, it is a good idea to call the Dispose method
        /// on the resulting data stream when finished.
        /// <para>This method only works on buffers with a Dynamic or Staging usage.  Immutable or default buffers will throw an exception when an attempt
        /// is made to lock them.</para>
        /// <para>Some buffers may raise an exception with locking with certain <paramref name="lockFlags"/>.  This is dependant upon the type of buffer.</para>
        /// <para>
        /// If the <paramref name="deferred"/> parameter is NULL (Nothing in VB.Net), the immediate context will be used to lock the buffer.  If it is non-NULL, then it
        /// will use the specified deferred context to clear the render target.
        /// <para>If you are using a deferred context, it is necessary to use that context to lock the buffer because 2 threads may not access the same resource at the same time.
        /// Passing a separate deferred context will alleviate that.</para>
        /// <para>When locking using a deferred context, either the NoOverwrite or Discard flags must be provided along with a Write flag.  No other flags will work.</para>
        /// </para>
        /// </remarks>
        /// <exception cref="GorgonLibrary.GorgonException">Thrown when the buffer is already locked.
        /// <para>-or-</para>
        /// <para>Thrown when the usage for the buffer does not allow the buffer to be locked.</para>
        /// </exception>
        /// <exception cref="System.ArgumentException">Thrown when a buffer is locked with with a read flag and with discard or nooverwrite.
        /// <para>-or-</para>
        /// <para>Thrown when the lock is used with a deferred graphics context and the NoOverwrite and/or the Discard flags are not present.</para>
        /// </exception>
        public GorgonDataStream Lock(BufferLockFlags lockFlags, GorgonGraphics deferred = null)
        {
#if DEBUG
            if ((Settings.Usage != BufferUsage.Staging) && (Settings.Usage != BufferUsage.Dynamic))
            {
                throw new GorgonException(GorgonResult.AccessDenied, string.Format(Resources.GORGFX_BUFFER_USAGE_CANT_LOCK, Settings.Usage));
            }

            if ((Settings.Usage != BufferUsage.Staging) && ((lockFlags & BufferLockFlags.Read) == BufferLockFlags.Read))
            {
                throw new GorgonException(GorgonResult.AccessDenied, Resources.GORGFX_LOCK_CANNOT_READ_NON_STAGING);
            }

            if ((((lockFlags & BufferLockFlags.NoOverwrite) == BufferLockFlags.NoOverwrite) ||
                 ((lockFlags & BufferLockFlags.Discard) == BufferLockFlags.Discard)) &&
                ((lockFlags & BufferLockFlags.Read) == BufferLockFlags.Read))
            {
                throw new ArgumentException(Resources.GORGFX_LOCK_CANNOT_USE_WITH_READ, "lockFlags");
            }

            if ((deferred != null) && (deferred.IsDeferred) &&
                (((lockFlags & BufferLockFlags.NoOverwrite) != BufferLockFlags.NoOverwrite) ||
                 ((lockFlags & BufferLockFlags.Discard) != BufferLockFlags.Discard)))
            {
                throw new ArgumentException(Resources.GORGFX_LOCK_NEED_DISCARD_NOOVERWRITE, "lockFlags");
            }
#endif

            if (deferred == null)
            {
                deferred = Graphics;
            }

            var result = OnLock(lockFlags, deferred);

            return(result);
        }
예제 #8
0
 /// <summary>
 /// Function to lock a CPU accessible texture sub resource for reading/writing.
 /// </summary>
 /// <param name="lockFlags">Flags used to lock.</param>
 /// <param name="mipLevel">[Optional] The mip-map level of the sub resource to lock.</param>
 /// <param name="deferred">[Optional] The deferred graphics context used to lock the texture.</param>
 /// <returns>A stream used to write to the texture.</returns>
 /// <remarks>This method is used to lock down a sub resource in the texture for reading/writing. When locking a texture, the entire texture sub resource is locked and returned.  There is no setting to return a portion of the texture subresource.
 /// <para>This method is only available to textures created with a staging or dynamic usage setting.  Otherwise an exception will be raised.</para>
 /// <para>Only the Write, Discard (with the Write flag) and Read flags may be used in the <paramref name="lockFlags"/> parameter.  The Read flag can only be used with staging textures and is mutually exclusive.</para>
 /// <para>If the <paramref name="deferred"/> parameter is NULL (Nothing in VB.Net), then the immediate context is used.  Use a deferred context to allow multiple threads to lock the
 /// texture at the same time.</para>
 /// </remarks>
 /// <returns>This method will return a <see cref="GorgonLibrary.Graphics.GorgonTextureLockData">GorgonTextureLockData</see> object containing information about the locked sub resource as well as
 /// a <see cref="GorgonLibrary.IO.GorgonDataStream">GorgonDataStream</see> that is used to access the locked sub resource data.</returns>
 /// <exception cref="System.ArgumentException">Thrown when the texture is not a dynamic or staging texture.
 /// <para>-or-</para>
 /// <para>Thrown when the texture is not a staging texture and the Read flag has been specified.</para>
 /// <para>-or-</para>
 /// <para>Thrown when the texture is not a dynamic texture and the discard flag has been specified.</para>
 /// </exception>
 /// <exception cref="System.ArgumentOutOfRangeException">Thrown when the <paramref name="mipLevel"/> parameter is less than 0, or larger than the mip count in the texture settings.</exception>
 public GorgonTextureLockData Lock(BufferLockFlags lockFlags,
                                   int mipLevel            = 0,
                                   GorgonGraphics deferred = null)
 {
     return(OnLock(lockFlags, 0, mipLevel, deferred));
 }