/// <summary> /// Function to create a new <see cref="GorgonRawReadWriteView"/> for this buffer. /// </summary> /// <param name="elementType">The type of data to interpret elements within the buffer as.</param> /// <param name="startElement">[Optional] The first element to start viewing from.</param> /// <param name="elementCount">[Optional] The number of elements to view.</param> /// <returns>A <see cref="GorgonRawReadWriteView"/> used to bind the buffer to a shader.</returns> /// <exception cref="GorgonException">Thrown when this buffer does not have a <see cref="BufferBinding"/> of <see cref="BufferBinding.ReadWrite"/>. /// <para>-or-</para> /// <para>Thrown when this buffer has a usage of <see cref="ResourceUsage.Staging"/>.</para> /// </exception> /// <remarks> /// <para> /// This will create an unordered access view that makes a buffer accessible to shaders using unordered access to the data. This allows viewing of the buffer data in a /// different format, or even a subsection of the buffer from within the shader. /// </para> /// <para> /// The <paramref name="elementType"/> parameter is used present the raw buffer data as another type to the shader. /// </para> /// <para> /// The <paramref name="startElement"/> parameter defines the starting data element to allow access to within the shader. If this value falls outside of the range of available elements, then it /// will be clipped to the upper and lower bounds of the element range. If this value is left at 0, then first element is viewed. /// </para> /// <para> /// To determine how many elements are in a buffer, use the <see cref="GetTotalElementCount"/> method. /// </para> /// <para> /// The <paramref name="elementCount"/> parameter defines how many elements to allow access to inside of the view. If this value falls outside of the range of available elements, then it will be /// clipped to the upper or lower bounds of the element range. If this value is left at 0, then the entire buffer is viewed. /// </para> /// </remarks> public GorgonRawReadWriteView GetRawReadWriteView(RawBufferElementType elementType, int startElement = 0, int elementCount = 0) { if ((Usage == ResourceUsage.Staging) || ((Binding & BufferBinding.ReadWrite) != BufferBinding.ReadWrite)) { throw new GorgonException(GorgonResult.CannotCreate, string.Format(Resources.GORGFX_ERR_UAV_RESOURCE_NOT_VALID, Name)); } // Ensure the size of the data type fits the requested format. int totalElementCount = GetTotalRawElementCount(); startElement = startElement.Min(totalElementCount - 1).Max(0); if (elementCount <= 0) { elementCount = totalElementCount - startElement; } elementCount = elementCount.Min(totalElementCount - startElement).Max(1); var key = new BufferShaderViewKey(startElement, elementCount, elementType); GorgonRawReadWriteView result = GetReadWriteView <GorgonRawReadWriteView>(key); if (result != null) { return(result); } result = new GorgonRawReadWriteView(this, startElement, elementCount, totalElementCount, elementType); result.CreateNativeView(); RegisterReadWriteView(key, result); return(result); }
/// <summary> /// Function to create a new <see cref="GorgonRawView"/> for this buffer. /// </summary> /// <param name="elementType">The type of data to interpret elements within the buffer as.</param> /// <param name="startElement">[Optional] The first element to start viewing from.</param> /// <param name="elementCount">[Optional] The number of elements to view.</param> /// <returns>A <see cref="GorgonRawReadWriteView"/> used to bind the buffer to a shader.</returns> /// <exception cref="GorgonException">Thrown when this buffer does not have a <see cref="BufferBinding"/> of <see cref="BufferBinding.ReadWrite"/>. /// <para>-or-</para> /// <para>Thrown when this buffer has a usage of <see cref="ResourceUsage.Staging"/>.</para> /// </exception> /// <remarks> /// <para> /// This will create a shader resource view that makes a buffer accessible to shaders. This allows viewing of the buffer data in a different format, or even a subsection of the buffer from within /// the shader. /// </para> /// <para> /// The <paramref name="elementType"/> parameter is used present the raw buffer data as another type to the shader. /// </para> /// <para> /// The <paramref name="startElement"/> parameter defines the starting data element to allow access to within the shader. If this value falls outside of the range of available elements, then it /// will be clipped to the upper and lower bounds of the element range. If this value is left at 0, then first element is viewed. /// </para> /// <para> /// To determine how many elements are in a buffer, use the <see cref="GetTotalElementCount"/> method. /// </para> /// <para> /// The <paramref name="elementCount"/> parameter defines how many elements to allow access to inside of the view. If this value falls outside of the range of available elements, then it will be /// clipped to the upper or lower bounds of the element range. If this value is left at 0, then the entire buffer is viewed. /// </para> /// </remarks> public GorgonRawView GetRawView(RawBufferElementType elementType, int startElement = 0, int elementCount = 0) { if ((Usage == ResourceUsage.Staging) || ((Binding & BufferBinding.Shader) != BufferBinding.Shader)) { throw new GorgonException(GorgonResult.CannotCreate, string.Format(Resources.GORGFX_ERR_SRV_NOT_VALID, Name)); } int totalElementCount = GetTotalRawElementCount(); startElement = startElement.Min(totalElementCount - 1).Max(0); // If we didn't specify a count, then do so now. if (elementCount < 1) { elementCount = totalElementCount - startElement; } elementCount = elementCount.Min(totalElementCount - startElement).Max(1); var key = new BufferShaderViewKey(startElement, elementCount, elementType); if (GetView(key) is GorgonRawView view) { return(view); } view = new GorgonRawView(this, elementType, startElement, elementCount, totalElementCount); view.CreateNativeView(); RegisterView(key, view); return(view); }
/// <summary> /// Function to create a new <see cref="GorgonVertexBufferReadWriteView"/> for this buffer. /// </summary> /// <param name="format">The format for the view.</param> /// <param name="startElement">[Optional] The first element to start viewing from.</param> /// <param name="elementCount">[Optional] The number of elements to view.</param> /// <returns>A <see cref="GorgonVertexBufferReadWriteView"/> used to bind the buffer to a shader.</returns> /// <exception cref="GorgonException">Thrown when this buffer does not have a <see cref="Binding"/> of <see cref="VertexIndexBufferBinding.UnorderedAccess"/>. /// <para>-or-</para> /// <para>Thrown when this buffer has a usage of <see cref="ResourceUsage.Staging"/>.</para> /// </exception> /// <exception cref="ArgumentException">Thrown when the <paramref name="format"/> is typeless or is not a supported format for unordered access views.</exception> /// <remarks> /// <para> /// This will create an unordered access view that makes a buffer accessible to shaders using unordered access to the data. This allows viewing of the buffer data in a /// different format, or even a subsection of the buffer from within the shader. /// </para> /// <para> /// The <paramref name="format"/> parameter is used present the buffer data as another format type to the shader. /// </para> /// <para> /// The <paramref name="startElement"/> parameter defines the starting data element to allow access to within the shader. If this value falls outside of the range of available elements, then it /// will be clipped to the upper and lower bounds of the element range. If this value is left at 0, then first element is viewed. /// </para> /// <para> /// The <paramref name="elementCount"/> parameter defines how many elements to allow access to inside of the view. If this value falls outside of the range of available elements, then it will be /// clipped to the upper or lower bounds of the element range. If this value is left at 0, then the entire buffer is viewed. /// </para> /// </remarks> public GorgonVertexBufferReadWriteView GetReadWriteView(BufferFormat format, int startElement = 0, int elementCount = 0) { if ((Usage == ResourceUsage.Staging) || ((Binding & VertexIndexBufferBinding.UnorderedAccess) != VertexIndexBufferBinding.UnorderedAccess)) { throw new GorgonException(GorgonResult.CannotCreate, string.Format(Resources.GORGFX_ERR_UAV_RESOURCE_NOT_VALID, Name)); } if (!Graphics.FormatSupport.TryGetValue(format, out IGorgonFormatSupportInfo support)) { throw new GorgonException(GorgonResult.CannotCreate, string.Format(Resources.GORGFX_ERR_UAV_FORMAT_INVALID, format)); } if ((support.FormatSupport & BufferFormatSupport.TypedUnorderedAccessView) != BufferFormatSupport.TypedUnorderedAccessView) { throw new ArgumentException(string.Format(Resources.GORGFX_ERR_UAV_FORMAT_INVALID, format), nameof(format)); } // Ensure the size of the data type fits the requested format. var info = new GorgonFormatInfo(format); if (info.IsTypeless) { throw new ArgumentException(Resources.GORGFX_ERR_VIEW_NO_TYPELESS, nameof(format)); } int totalElementCount = GetTotalElementCount(info); startElement = startElement.Min(totalElementCount - 1).Max(0); if (elementCount <= 0) { elementCount = totalElementCount - startElement; } elementCount = elementCount.Min(totalElementCount - startElement).Max(1); var key = new BufferShaderViewKey(startElement, elementCount, format); GorgonVertexBufferReadWriteView result = GetReadWriteView <GorgonVertexBufferReadWriteView>(key); if (result != null) { return(result); } result = new GorgonVertexBufferReadWriteView(this, format, info, startElement, elementCount, totalElementCount); result.CreateNativeView(); RegisterReadWriteView(key, result); return(result); }
/// <summary> /// Function to create or retrieve a <see cref="GorgonBufferView"/> for this buffer. /// </summary> /// <param name="format">The format of the view</param> /// <param name="startElement">[Optional] The starting element to begin viewing at.</param> /// <param name="elementCount">[Optional] The number of elements to view.</param> /// <returns>The <see cref="GorgonBufferView"/> requested for this buffer.</returns> /// <exception cref="GorgonException">Thrown if this buffer is a staging resource, or does not have a binding flag for shader access.</exception> /// <exception cref="ArgumentException">Thrown if the <paramref name="format"/> is typeless.</exception> /// <remarks> /// <para> /// This will create a shader resource view that makes a buffer accessible to shaders. This allows viewing of the buffer data in a different format, or even a subsection of the buffer from within /// the shader. /// </para> /// <para> /// The <paramref name="format"/> parameter is used present the buffer data as a specific <see cref="BufferFormat"/> type to the shader. /// </para> /// <para> /// The <paramref name="startElement"/> parameter defines the starting data element to allow access to within the shader. If this value falls outside of the range of available elements, then it /// will be clipped to the upper and lower bounds of the element range. If this value is left at 0, then first element is viewed. /// </para> /// <para> /// The <paramref name="elementCount"/> parameter defines how many elements to allow access to inside of the view. If this value falls outside of the range of available elements, then it will be /// clipped to the upper or lower bounds of the element range. If this value is left at 0, then the entire buffer is viewed. /// </para> /// </remarks> /// <seealso cref="BufferFormat"/> public GorgonBufferView GetShaderResourceView(BufferFormat format, int startElement = 0, int elementCount = 0) { if (format == BufferFormat.Unknown) { throw new ArgumentException(Resources.GORGFX_ERR_VIEW_UNKNOWN_FORMAT, nameof(format)); } if (Usage == ResourceUsage.Staging) { throw new GorgonException(GorgonResult.CannotCreate, Resources.GORGFX_ERR_BUFFER_STAGING_CANNOT_BE_BOUND_TO_GPU); } if ((Binding & BufferBinding.Shader) != BufferBinding.Shader) { throw new GorgonException(GorgonResult.CannotCreate, string.Format(Resources.GORGFX_ERR_BUFFER_INCORRECT_BINDING, BufferBinding.Shader)); } var formatInfo = new GorgonFormatInfo(format); if (formatInfo.IsTypeless) { throw new ArgumentException(string.Format(Resources.GORGFX_ERR_VIEW_NO_TYPELESS)); } int totalElementCount = GetTotalElementCount(formatInfo); startElement = startElement.Min(totalElementCount - 1).Max(0); // If we didn't specify a count, then do so now. if (elementCount < 1) { elementCount = totalElementCount - startElement; } elementCount = elementCount.Min(totalElementCount - startElement).Max(1); var key = new BufferShaderViewKey(startElement, elementCount, format); if (GetView(key) is GorgonBufferView view) { return(view); } view = new GorgonBufferView(this, format, formatInfo, startElement, elementCount, totalElementCount); view.CreateNativeView(); RegisterView(key, view); return(view); }
/// <summary> /// Function to create or retrieve a <see cref="GorgonStructuredView"/> for this buffer. /// </summary> /// <param name="startElement">[Optional] The starting element to begin viewing at.</param> /// <param name="elementCount">[Optional] The number of elements to view.</param> /// <returns>The <see cref="GorgonStructuredView"/> requested for this buffer.</returns> /// <exception cref="GorgonException">Thrown if this buffer is a staging resource, or does not have a binding flag for shader access.</exception> /// <remarks> /// <para> /// This will create an unordered access view that makes a buffer accessible to shaders. This allows viewing of the buffer data in a different format, or even a subsection of the buffer from within /// the shader. /// </para> /// <para> /// The <paramref name="startElement"/> parameter defines the starting data element to allow access to within the shader. If this value falls outside of the range of available elements, then it /// will be clipped to the upper and lower bounds of the element range. If this value is left at 0, then first element is viewed. /// </para> /// <para> /// The <paramref name="elementCount"/> parameter defines how many elements to allow access to inside of the view. If this value falls outside of the range of available elements, then it will be /// clipped to the upper or lower bounds of the element range. If this value is left at 0, then the entire buffer is viewed. /// </para> /// </remarks> public GorgonStructuredView GetStructuredView(int startElement = 0, int elementCount = 0) { if (Usage == ResourceUsage.Staging) { throw new GorgonException(GorgonResult.CannotCreate, Resources.GORGFX_ERR_BUFFER_STAGING_CANNOT_BE_BOUND_TO_GPU); } if ((Binding & BufferBinding.Shader) != BufferBinding.Shader) { throw new GorgonException(GorgonResult.CannotCreate, string.Format(Resources.GORGFX_ERR_BUFFER_INCORRECT_BINDING, BufferBinding.Shader)); } int totalElementCount = GetTotalStructuredElementCount(); startElement = startElement.Max(0); // If we didn't specify a count, then do so now. if (elementCount < 1) { elementCount = totalElementCount - startElement; } elementCount = elementCount.Min(totalElementCount - startElement).Max(1); var key = new BufferShaderViewKey(startElement, elementCount, 0); if (GetView(key) is GorgonStructuredView view) { return(view); } view = new GorgonStructuredView(this, startElement, elementCount, totalElementCount); view.CreateNativeView(); RegisterView(key, view); return(view); }