/// <summary> /// Initializes a new instance of the <see cref="GorgonStructuredBufferUnorderedAccessView"/> class. /// </summary> /// <param name="resource">The buffer to bind to the view.</param> /// <param name="firstElement">The first element in the buffer.</param> /// <param name="elementCount">The number of elements to view.</param> /// <param name="viewType">The type of unordered access view.</param> internal GorgonStructuredBufferUnorderedAccessView(GorgonResource resource, int firstElement, int elementCount, UnorderedAccessViewType viewType) : base(resource, BufferFormat.Unknown, firstElement, elementCount, false) { ViewType = viewType; InitialCount = -1; _structuredBuffer = (GorgonStructuredBuffer)resource; }
/// <summary> /// Function to create/retrieve an unordered access view in the cache. /// </summary> /// <param name="format">Format of the unordered access view.</param> /// <param name="mipSliceElementStart">Mip slice for a texture, element start for a buffer.</param> /// <param name="arrayIndexElementCount">Array index for a texture, element count for a buffer.</param> /// <param name="arrayCount">Array count for a texture.</param> /// <param name="viewType">View type for structured buffers.</param> /// <param name="isRaw">TRUE for raw views, FALSE for normal.</param> /// <returns>The cached unordered access view.</returns> public GorgonUnorderedAccessView GetUnorderedAccessView(BufferFormat format, int mipSliceElementStart, int arrayIndexElementCount, int arrayCount, UnorderedAccessViewType viewType, bool isRaw) { var key = new ViewKey(format, mipSliceElementStart, arrayIndexElementCount, arrayCount, ((int)viewType) + (isRaw ? 10 : 0)); lock (_syncLock) { GorgonUnorderedAccessView result; if (_unorderedViews.TryGetValue(key, out result)) { return(result); } switch (_resource.ResourceType) { case ResourceType.Buffer: if (_resource is GorgonStructuredBuffer) { result = new GorgonStructuredBufferUnorderedAccessView(_resource, mipSliceElementStart, arrayIndexElementCount, viewType); } else { result = new GorgonBufferUnorderedAccessView(_resource, format, mipSliceElementStart, arrayIndexElementCount, isRaw); } break; case ResourceType.Texture1D: case ResourceType.Texture2D: case ResourceType.Texture3D: result = new GorgonTextureUnorderedAccessView(_resource, format, mipSliceElementStart, arrayIndexElementCount, arrayCount); break; } // This should never happen. if (result == null) { throw new GorgonException(GorgonResult.CannotCreate, string.Format(Resources.GORGFX_IMAGE_TYPE_INVALID, _resource.ResourceType)); } result.Initialize(); _unorderedViews.Add(key, result); return(result); } }
/// <summary> /// Function to retrieve an unordered access view for this buffer. /// </summary> /// <param name="format">Format of the buffer.</param> /// <param name="start">First element to map to the view.</param> /// <param name="count">The number of elements to map to the view.</param> /// <param name="isRaw">TRUE if using a raw view to the buffer, FALSE if not.</param> /// <param name="viewType">The type of view for a structured buffer.</param> /// <returns>An unordered access view for the buffer.</returns> /// <remarks>Use this to create/retrieve an unordered access view that will allow shaders to access the view using multiple threads at the same time. Unlike a Shader View, only one /// unordered access view can be bound to the pipeline at any given time. /// <para>Raw views require that the format be set to R32 (typeless).</para> /// <para>Unordered access views require a video device feature level of SM_5 or better.</para> /// </remarks> /// <exception cref="GorgonLibrary.GorgonException">Thrown when the usage for this buffer is set to Staging or Dynamic. /// <para>-or-</para> /// <para>Thrown when the video device feature level is not SM_5 or better.</para> /// <para>-or-</para> /// <para>Thrown when the resource settings do not allow unordered access views.</para> /// <para>-or-</para> /// <para>Thrown when the view could not be created.</para> /// </exception> /// <exception cref="System.ArgumentException">Thrown when the <paramref name="start"/> or <paramref name="count"/> parameters are less than 0 or greater than or equal to the /// number of elements in the buffer.</exception> protected GorgonBufferUnorderedAccessView OnGetUnorderedAccessView(BufferFormat format, int start, int count, bool isRaw, UnorderedAccessViewType viewType) { int elementCount; if (Graphics.VideoDevice.SupportedFeatureLevel < DeviceFeatureLevel.SM5) { throw new GorgonException(GorgonResult.CannotCreate, string.Format(Resources.GORGFX_REQUIRES_SM, "SM5")); } if (!Settings.AllowUnorderedAccessViews) { throw new GorgonException(GorgonResult.CannotCreate, string.Format(Resources.GORGFX_VIEW_NO_SUPPORT, "GorgonUnorderedAccessView")); } if ((Settings.Usage == BufferUsage.Staging) || (Settings.Usage == BufferUsage.Dynamic)) { throw new GorgonException(GorgonResult.CannotBind, Resources.GORGFX_VIEW_UNORDERED_NO_STAGING_DYNAMIC); } if (BufferType != BufferType.Structured) { if (format == BufferFormat.Unknown) { throw new ArgumentException(Resources.GORGFX_VIEW_UNKNOWN_FORMAT, "format"); } if (Settings.AllowRawViews) { if (format != BufferFormat.R32) { throw new GorgonException(GorgonResult.CannotBind, Resources.GORGFX_VIEW_UNORDERED_RAW_INVALID_FORMAT); } elementCount = SizeInBytes / 4; } else { // Ensure the size of the data type fits the requested format. var info = GorgonBufferFormatInfo.GetInfo(format); elementCount = SizeInBytes / info.SizeInBytes; } } else { isRaw = false; elementCount = SizeInBytes / Settings.StructureSize; format = BufferFormat.Unknown; } if (((start + count) > elementCount) || (start < 0) || (count < 1)) { throw new ArgumentException(string.Format(Resources.GORGFX_VIEW_ELEMENT_OUT_OF_RANGE, elementCount, (elementCount - start))); } if (BufferType == BufferType.Structured) { return((GorgonBufferUnorderedAccessView)_viewCache.GetUnorderedAccessView(format, start, count, 0, viewType, isRaw)); } if (!Graphics.VideoDevice.SupportsUnorderedAccessViewFormat(format)) { throw new GorgonException(GorgonResult.CannotCreate, string.Format(Resources.GORGFX_VIEW_FORMAT_NOT_SUPPORTED, format)); } return((GorgonBufferUnorderedAccessView)_viewCache.GetUnorderedAccessView(format, start, count, 0, viewType, isRaw)); }
public UAVDescription(string name, ShaderStage shaderType, UnorderedAccessViewType type) { Name = name; ShaderType = shaderType; Type = type; }
/// <summary> /// Function to retrieve an unordered access view for this buffer. /// </summary> /// <param name="start">First element to map to the view.</param> /// <param name="count">The number of elements to map to the view.</param> /// <param name="viewType">The type of unordered view to apply to the structured buffer.</param> /// <returns>A new unordered access view for the buffer.</returns> /// <remarks>Use this to create/retrieve an unordered access view that will allow shaders to access the view using multiple threads at the same time. Unlike a <see cref="GetShaderView">Shader View</see>, only one /// unordered access view can be bound to the pipeline at any given time. /// <para>Unordered access views require a video device feature level of SM_5 or better.</para> /// </remarks> /// <exception cref="GorgonLibrary.GorgonException">Thrown when the view could not be created or retrieved from the cache.</exception> /// <exception cref="System.ArgumentException">Thrown when the <paramref name="start"/> or <paramref name="count"/> parameters are less than 0 or greater than or equal to the /// number of elements in the buffer.</exception> public GorgonStructuredBufferUnorderedAccessView GetUnorderedAccessView(int start, int count, UnorderedAccessViewType viewType) { return((GorgonStructuredBufferUnorderedAccessView)OnGetUnorderedAccessView(BufferFormat.Unknown, start, count, false, viewType)); }