/// <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)); }
public override GorgonTextureLockData Lock(BufferLockFlags lockFlags, int arrayIndex = 0, int mipLevel = 0, GorgonGraphics deferred = null) { throw new NotSupportedException(Resources.GORGFX_DEPTH_OPERATION_NOT_SUPPORTED); }
/// <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)); }
/// <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)); }
/// <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); }
/// <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); } }
/// <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); }
/// <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)); }