예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
        /// <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);
        }