Esempio n. 1
0
        /// <summary>
        /// Function to retrieve a render target view.
        /// </summary>
        /// <param name="format">Format of the new render target view.</param>
        /// <param name="bufferFormat">The format of the buffer.</param>
        /// <param name="firstElement">The first element in the buffer to map to the view.</param>
        /// <param name="elementCount">The number of elements in the buffer to map to the view.</param>
        /// <returns>A render target view.</returns>
        /// <remarks>Use this to create/retrieve a render target view that can bind a portion of the target to the pipeline as a render target.
        /// <para>The <paramref name="format"/> for the render target view does not have to be the same as the render target backing buffer, and if the format is set to Unknown, then it will
        /// use the format from the buffer.</para>
        /// </remarks>
        /// <exception cref="GorgonLibrary.GorgonException">Thrown when the view could not created or retrieved from the internal cache.</exception>
        protected GorgonRenderTargetBufferView OnGetRenderTargetView(BufferFormat format, BufferFormat bufferFormat, int firstElement, int elementCount)
        {
            // If we pass unknown, use the format from the texture.
            if (format == BufferFormat.Unknown)
            {
                format = bufferFormat;
            }

            var info = GorgonBufferFormatInfo.GetInfo(format);

            if (info.IsTypeless)
            {
                throw new GorgonException(GorgonResult.CannotCreate, Resources.GORGFX_VIEW_NO_TYPELESS);
            }

            var bufferElementCount = Settings.SizeInBytes / info.SizeInBytes;

            if ((firstElement < 0) || (firstElement >= bufferElementCount) ||
                (elementCount < 1) || (elementCount >= bufferElementCount))
            {
                throw new GorgonException(GorgonResult.CannotCreate,
                                          string.Format(Resources.GORGFX_VIEW_ELEMENT_OUT_OF_RANGE, elementCount, elementCount));
            }


            return((GorgonRenderTargetBufferView)_viewCache.GetRenderTargetView(format, firstElement, elementCount, 0));
        }
Esempio n. 2
0
        /// <summary>
        /// Function to create a list of buffers to use.
        /// </summary>
        /// <param name="data">Data to copy/reference.</param>
        internal unsafe void CreateBuffers(byte *data)
        {
            int bufferIndex = 0;
            var formatInfo  = GorgonBufferFormatInfo.GetInfo(_image.Settings.Format);                   // Format information.

            // Allocate enough room for the array and mip levels.
            _buffers = new GorgonImageBuffer[GorgonImageData.GetDepthSliceCount(_image.Settings.Depth, _image.Settings.MipCount) * _image.Settings.ArrayCount];

            MipOffsetSize = new Tuple <int, int> [_image.Settings.MipCount * _image.Settings.ArrayCount];               // Offsets for the mip maps.
            DataBoxes     = new DX.DataBox[_image.Settings.ArrayCount * _image.Settings.MipCount];                      // Create the data boxes for textures.

            // Enumerate array indices. (For 1D and 2D only, 3D will always be 1)
            for (int array = 0; array < _image.Settings.ArrayCount; array++)
            {
                int mipWidth  = _image.Settings.Width;
                int mipHeight = _image.Settings.Height;
                int mipDepth  = _image.Settings.Depth;

                // Enumerate mip map levels.
                for (int mip = 0; mip < _image.Settings.MipCount; mip++)
                {
                    int arrayIndex       = mip + (array * _image.Settings.MipCount);
                    var pitchInformation = formatInfo.GetPitch(mipWidth, mipHeight, PitchFlags.None);

                    // Get data box for texture upload.
                    DataBoxes[arrayIndex] = new DX.DataBox(new IntPtr(data), pitchInformation.RowPitch, pitchInformation.SlicePitch);

                    // Calculate buffer offset by mip.
                    MipOffsetSize[arrayIndex] = new Tuple <int, int>(bufferIndex, mipDepth);

                    // Enumerate depth slices.
                    for (int depth = 0; depth < mipDepth; depth++)
                    {
                        // Get mip information.
                        _buffers[bufferIndex] = new GorgonImageBuffer(data, pitchInformation, mip, array, depth, mipWidth, mipHeight,
                                                                      mipDepth, _image.Settings.Format);

                        data += pitchInformation.SlicePitch;
                        bufferIndex++;
                    }

                    if (mipWidth > 1)
                    {
                        mipWidth >>= 1;
                    }
                    if (mipHeight > 1)
                    {
                        mipHeight >>= 1;
                    }
                    if (mipDepth > 1)
                    {
                        mipDepth >>= 1;
                    }
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Function to create the default shader view.
        /// </summary>
        protected virtual void OnCreateDefaultShaderView()
        {
            // Staging buffers cannot create shader views.
            if ((Settings.Usage == BufferUsage.Staging) ||
                (Settings.DefaultShaderViewFormat == BufferFormat.Unknown))
            {
                return;
            }

            var info = GorgonBufferFormatInfo.GetInfo(Settings.DefaultShaderViewFormat);

            DefaultShaderView = OnGetShaderView(Settings.DefaultShaderViewFormat, 0,
                                                Settings.SizeInBytes / info.SizeInBytes, false);
        }
Esempio n. 4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="GorgonInputElement"/> class.
        /// </summary>
        /// <param name="context">The context for the element.</param>
        /// <param name="format">The format and type of the element.</param>
        /// <param name="offset">The offset of the element within the vertex.</param>
        /// <param name="index">The index of the element.</param>
        /// <param name="slot">The vertex buffer slot for the element.</param>
        /// <param name="instanced">TRUE if using instanced data, FALSE if not.</param>
        /// <param name="instanceCount">Number of instances to use before moving to the next element.</param>
        /// <remarks>The slot value must be between 0 and 15 (inclusive).  A value outside of this range will cause an exception to be thrown.</remarks>
        /// <exception cref="System.ArgumentException">Thrown when the <paramref name="format"/> parameter is not supported.</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Thrown when the <paramref name="slot"/> parameter is less than 0 or greater than 15.</exception>
        public GorgonInputElement(string context, BufferFormat format, int offset, int index, int slot, bool instanced, int instanceCount)
        {
            if (GorgonBufferFormatInfo.GetInfo(format).BitDepth == 0)
            {
                throw new ArgumentException(string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, format), "format");
            }

            if ((slot < 0) || (slot > 15))
            {
                throw new ArgumentOutOfRangeException("slot", string.Format(Resources.GORGFX_VALUE_OUT_OF_RANGE, slot, 16));
            }

            Context       = context;
            Index         = index;
            Format        = format;
            Offset        = offset;
            Size          = GorgonBufferFormatInfo.GetInfo(format).SizeInBytes;
            Slot          = slot;
            Instanced     = instanced;
            InstanceCount = instanceCount;
        }
Esempio n. 5
0
        /// <summary>
        /// Function to retrieve a new shader view for the buffer.
        /// </summary>
        /// <param name="format">The format of the view.</param>
        /// <param name="start">Starting element.</param>
        /// <param name="count">Element count.</param>
        /// <param name="isRaw">TRUE if using a raw view of the buffer, FALSE if not.</param>
        /// <returns>A shader view for the buffer.</returns>
        /// <exception cref="GorgonLibrary.GorgonException">Thrown when the usage for this buffer is set to Staging.
        /// <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>
        /// <remarks>Use this to create/retrieve additional shader views for the buffer.  Multiple views of the same resource can be bound to multiple stages in the pipeline.
        /// <para>Raw views require that the buffer be created with the <see cref="GorgonLibrary.Graphics.IBufferSettings.AllowRawViews">AllowRawViews</see> property set to TRUE in its settings.</para>
        /// <para>Raw views can only be used on SM5 video devices or better. </para>
        /// <para>This function only applies to buffers that have not been created with a Usage of Staging.</para>
        /// </remarks>
        protected GorgonBufferShaderView OnGetShaderView(BufferFormat format, int start, int count, bool isRaw)
        {
            int elementCount;

            if (Settings.Usage == BufferUsage.Staging)
            {
                throw new GorgonException(GorgonResult.CannotCreate, Resources.GORGFX_VIEW_SRV_NO_STAGING_OR_DYNAMIC);
            }

            if (!Settings.AllowShaderViews)
            {
                throw new GorgonException(GorgonResult.CannotCreate, string.Format(Resources.GORGFX_VIEW_NO_SUPPORT, "GorgonShaderView"));
            }

            // If we're using any other type than structured...
            if (BufferType != BufferType.Structured)
            {
                if (format == BufferFormat.Unknown)
                {
                    throw new ArgumentException(Resources.GORGFX_VIEW_UNKNOWN_FORMAT, "format");
                }

                // Ensure the size of the data type fits the requested format.
                var info = GorgonBufferFormatInfo.GetInfo(format);

                if (info.IsTypeless)
                {
                    throw new GorgonException(GorgonResult.CannotCreate, Resources.GORGFX_VIEW_NO_TYPELESS);
                }

                if (isRaw)
                {
                    if (Graphics.VideoDevice.SupportedFeatureLevel < DeviceFeatureLevel.SM5)
                    {
                        throw new GorgonException(GorgonResult.CannotCreate,
                                                  string.Format(Resources.GORGFX_REQUIRES_SM, "SM5"));
                    }

                    if (!Settings.AllowRawViews)
                    {
                        throw new GorgonException(GorgonResult.CannotBind, Resources.GORGFX_BUFFER_NO_RAW_VIEWS);
                    }

                    if (info.Group != BufferFormat.R32)
                    {
                        throw new GorgonException(GorgonResult.CannotBind, Resources.GORGFX_VIEW_RAW_INVALID_FORMAT);
                    }

                    elementCount = SizeInBytes / 4;
                }
                else
                {
                    elementCount = SizeInBytes / info.SizeInBytes;
                }
            }
            else
            {
                // We cannot use structured buffers on anything less than a SM5 video device.
                if (Graphics.VideoDevice.SupportedFeatureLevel < DeviceFeatureLevel.SM5)
                {
                    throw new GorgonException(GorgonResult.CannotCreate,
                                              string.Format(Resources.GORGFX_REQUIRES_SM, "SM5"));
                }

                elementCount = Settings.SizeInBytes / Settings.StructureSize;
                format       = BufferFormat.Unknown;
                isRaw        = false;
            }

            if (((start + count) > elementCount) ||
                (start < 0) ||
                (count < 1))
            {
                throw new ArgumentException(string.Format(Resources.GORGFX_VIEW_ELEMENT_OUT_OF_RANGE, elementCount,
                                                          (elementCount - start)));
            }

            return(_viewCache.GetBufferView(format, start, count, isRaw));
        }
Esempio n. 6
0
        /// <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));
        }
Esempio n. 7
0
        /// <summary>
        /// Function to resolve a multisampled texture resource into another non-multisampled resource.
        /// </summary>
        /// <param name="destination">The texture that will receive the resolved texture.</param>
        /// <param name="destArrayIndex">[Optional] Index in the array that will receive the resolved texture data.</param>
        /// <param name="destMipLevel">[Optional] The mip map level that will receive the resolved texture data.</param>
        /// <param name="srcArrayIndex">[Optional] The array index in the source to resolve.</param>
        /// <param name="srcMipLevel">[Optional] The source mip level to resolve.</param>
        /// <param name="resolveFormat">[Optional] A format that will determine how to resolve the multisampled texture into a non-multisampled texture.</param>
        /// <param name="context">[Optional] A deferred graphics context used to copy the data.</param>
        /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="destination"/> parameter is NULL (Nothing in VB.Net).</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Thrown when the <paramref name="destArrayIndex"/>, <paramref name="destMipLevel"/>, <paramref name="srcArrayIndex"/>, or the
        /// <paramref name="srcMipLevel"/> parameters are not within the the range of the array indices or mip levels of the respective textures.</exception>
        /// <exception cref="System.NotSupportedException">Thrown when the source texture is not multisampled or the destination texture is multisampled or has a non default usage.</exception>
        /// <exception cref="System.ArgumentException">Thrown when the <paramref name="resolveFormat"/> is not compatible with the formats of the source or destination texture.</exception>
        /// <remarks>Use this method to resolve a multisampled texture into a non multisampled texture.  This is most useful when transferring a multisampled render target pass as an input to
        /// a secondary pass.
        /// <para>The <paramref name="resolveFormat"/> parameter is used to determine how to interpret the data in the texture.  There are 3 ways this data may be interpreted:
        /// <list type="number">
        /// <item><description>If both textures have a typed format, then the resolve format must be the same as the format of the textures.  Both textures must have the same format.</description></item>
        /// <item><description>If one of the textures have a typeless format and one has a typed format, then the resolve format must be in the same group as the typed format.</description></item>
        /// <item><description>If the textures both have a typeless format, then the resolve format must be in the same group as the typeless format.</description></item>
        /// </list>
        /// Leaving the resolve format as Unknown will automatically use the format of the source texture.
        /// </para>
        /// <para>If the <paramref name="context"/> parameter is NULL (Nothing in VB.Net) then the immediate context will be used.  If this method is called from multiple threads, then a deferred context should be passed for each thread that is
        /// accessing the sub resource.</para>
        /// </remarks>
        public void ResolveTo(GorgonTexture destination,
                              int destArrayIndex         = 0,
                              int destMipLevel           = 0,
                              int srcArrayIndex          = 0,
                              int srcMipLevel            = 0,
                              BufferFormat resolveFormat = BufferFormat.Unknown,
                              GorgonGraphics context     = null)
        {
            if (resolveFormat == BufferFormat.Unknown)
            {
                resolveFormat = Settings.Format;
            }

#if DEBUG
            if (destination == null)
            {
                throw new ArgumentNullException("destination");
            }

            if ((destArrayIndex >= destination.Settings.ArrayCount) &&
                (destArrayIndex < 0))
            {
                throw new ArgumentOutOfRangeException("destArrayIndex",
                                                      string.Format(Resources.GORGFX_ARG_OUT_OF_RANGE,
                                                                    0,
                                                                    destination.Settings.ArrayCount));
            }

            if ((destMipLevel < 0) || (destMipLevel >= destination.Settings.MipCount))
            {
                throw new ArgumentOutOfRangeException("destMipLevel", string.Format(Resources.GORGFX_ARG_OUT_OF_RANGE, 0,
                                                                                    destination.Settings.MipCount));
            }

            if ((srcArrayIndex >= Settings.ArrayCount) &&
                (srcArrayIndex < 0))
            {
                throw new ArgumentOutOfRangeException("srcArrayIndex",
                                                      string.Format(Resources.GORGFX_ARG_OUT_OF_RANGE,
                                                                    0,
                                                                    Settings.ArrayCount));
            }

            if ((srcMipLevel < 0) || (srcMipLevel >= Settings.MipCount))
            {
                throw new ArgumentOutOfRangeException("srcMipLevel", string.Format(Resources.GORGFX_ARG_OUT_OF_RANGE, 0,
                                                                                   Settings.MipCount));
            }

            if (Settings.Multisampling.Equals(GorgonMultisampling.NoMultiSampling))
            {
                throw new NotSupportedException(string.Format(Resources.GORGFX_TEXTURE_SRC_NOT_MULTISAMPLED, Name));
            }

            if (destination.Settings.Usage != BufferUsage.Default)
            {
                throw new NotSupportedException(string.Format(Resources.GORGFX_TEXTURE_RESOLVE_DEST_NOT_DEFAULT, destination.Name));
            }

            var srcFormatInfo     = GorgonBufferFormatInfo.GetInfo(Settings.Format);
            var destFormatInfo    = GorgonBufferFormatInfo.GetInfo(destination.Settings.Format);
            var resolveFormatInfo = GorgonBufferFormatInfo.GetInfo(resolveFormat);

            // Ensure that the resource formats and resolve format all match up.
            if ((!srcFormatInfo.IsTypeless) && (!destFormatInfo.IsTypeless))
            {
                if (Settings.Format != destination.Settings.Format)
                {
                    throw new ArgumentException(string.Format(Resources.GORGFX_TEXTURE_RESOLVE_FORMATS_NOT_SAME, Settings.Format),
                                                "destination");
                }

                if (resolveFormat != Settings.Format)
                {
                    throw new ArgumentException(string.Format(Resources.GORGFX_TEXTURE_RESOLVE_FORMAT_MUST_BE_UNKNOWN), "resolveFormat");
                }
            }
            else if ((srcFormatInfo.IsTypeless) && (destFormatInfo.IsTypeless))
            {
                if (Settings.Format != destination.Settings.Format)
                {
                    throw new ArgumentException(string.Format(Resources.GORGFX_TEXTURE_RESOLVE_FORMATS_NOT_SAME, Settings.Format),
                                                "destination");
                }

                if ((resolveFormatInfo.Group != srcFormatInfo.Group) ||
                    (resolveFormatInfo.Group != destFormatInfo.Group))
                {
                    throw new ArgumentException(
                              string.Format(Resources.GORGFX_TEXTURE_RESOLVE_FORMAT_NOT_SAME_GROUP, Settings.Format),
                              "resolveFormat");
                }
            }
            else if ((srcFormatInfo.IsTypeless) || (destFormatInfo.IsTypeless))
            {
                if (resolveFormatInfo.IsTypeless)
                {
                    throw new ArgumentException(string.Format(Resources.GORGFX_TEXTURE_RESOLVE_FORMAT_CANNOT_BE_TYPELESS),
                                                "resolveFormat");
                }

                if (srcFormatInfo.Group != destFormatInfo.Group)
                {
                    throw new ArgumentException(
                              string.Format(Resources.GORGFX_TEXTURE_RESOLVE_SRC_DEST_NOT_SAME_GROUP,
                                            Settings.Format,
                                            destination.Settings.Format),
                              "destination");
                }
            }
#endif

            int sourceIndex = D3D.Resource.CalculateSubResourceIndex(srcMipLevel, srcArrayIndex, Settings.MipCount);
            int destIndex   = D3D.Resource.CalculateSubResourceIndex(destMipLevel,
                                                                     destArrayIndex,
                                                                     destination.Settings.MipCount);

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

            context.Context.ResolveSubresource(D3DResource, sourceIndex, destination.D3DResource, destIndex, (GI.Format)resolveFormat);
        }