Ejemplo n.º 1
0
        /// <summary>
        /// Function to create a new depth/stencil buffer that is bindable to the GPU.
        /// </summary>
        /// <param name="graphics">The graphics interface to use when creating the target.</param>
        /// <param name="info">The information about the depth/stencil texture.</param>
        /// <param name="viewFlags">[Optional] Flags used to determine if the depth buffer/stencil can be read by the GPU or not.</param>
        /// <returns>A new <see cref="GorgonDepthStencil2DView"/>.</returns>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="graphics"/>, or <paramref name="info"/> parameter is <b>null</b>.</exception>
        /// <remarks>
        /// <para>
        /// This is a convenience method that will create a <see cref="GorgonTexture2D"/> and a <see cref="GorgonDepthStencil2DView"/> as a single object that users can use to apply a depth/stencil texture.
        /// This helps simplify creation of a render target by executing some prerequisite steps on behalf of the user.
        /// </para>
        /// <para>
        /// Since the <see cref="GorgonTexture2D"/> created by this method is linked to the <see cref="GorgonDepthStencil2DView"/> returned, disposal of either one will dispose of the other on your behalf.
        /// If the user created a <see cref="GorgonDepthStencil2DView"/> from the <see cref="GorgonTexture2D.GetRenderTargetView"/> method on the <see cref="GorgonTexture2D"/>, then it's assumed the user
        /// knows what they are doing and will handle the disposal of the texture and view on their own.
        /// </para>
        /// <para>
        /// To make the texture bindable on the GPU as a shader resource view, set the <see cref="IGorgonTexture2DInfo.Binding"/> to include the <see cref="TextureBinding.ShaderResource"/> flag in the value
        /// and set the <paramref name="viewFlags"/> to <see cref="DepthStencilViewFlags.ReadOnlyDepth"/>, <see cref="DepthStencilViewFlags.ReadOnlyStencil"/> or both.
        /// </para>
        /// </remarks>
        /// <seealso cref="GorgonTexture2D"/>
        public static GorgonDepthStencil2DView CreateDepthStencil(GorgonGraphics graphics, IGorgonTexture2DInfo info, DepthStencilViewFlags viewFlags = DepthStencilViewFlags.None)
        {
            if (graphics == null)
            {
                throw new ArgumentNullException(nameof(graphics));
            }

            if (info == null)
            {
                throw new ArgumentNullException(nameof(info));
            }

            TextureBinding binding = TextureBinding.DepthStencil;

            if ((info.Binding & TextureBinding.ShaderResource) == TextureBinding.ShaderResource)
            {
                if (viewFlags != DepthStencilViewFlags.None)
                {
                    binding |= TextureBinding.ShaderResource;
                }
                else
                {
                    // Do this to notify the user that something is amiss.
                    graphics.Log.Print($"WARNING: Depth Stencil View {info.Name} - Depth/stencil texture has a binding of {TextureBinding.ShaderResource}, but has a view flags of {viewFlags}.  The view will not be bindable to the shader pipeline.",
                                       LoggingLevel.Simple);
                }
            }
            else if (viewFlags != DepthStencilViewFlags.None)
            {
                // Do this to notify the user that something is amiss.
                graphics.Log.Print($"WARNING: Depth Stencil View {info.Name} - Depth/stencil view flag(s) are set to {viewFlags}, but the texture lacks a {TextureBinding.ShaderResource} binding.",
                                   LoggingLevel.Simple);
            }

            var newInfo = new GorgonTexture2DInfo(info)
            {
                // Can't see a reason to use anything other than default for dsvs
                Usage   = ResourceUsage.Default,
                Binding = binding
            };

            BufferFormat depthStencilFormat = newInfo.Format;

            if (((binding & TextureBinding.ShaderResource) == TextureBinding.ShaderResource) &&
                (viewFlags != DepthStencilViewFlags.None))
            {
                switch (newInfo.Format)
                {
                case BufferFormat.R32G8X24_Typeless:
                    depthStencilFormat = BufferFormat.D32_Float_S8X24_UInt;
                    break;

                case BufferFormat.R24G8_Typeless:
                    depthStencilFormat = BufferFormat.D24_UNorm_S8_UInt;
                    break;

                case BufferFormat.R16_Typeless:
                    depthStencilFormat = BufferFormat.D16_UNorm;
                    break;

                case BufferFormat.R32_Typeless:
                    depthStencilFormat = BufferFormat.D32_Float;
                    break;
                }
            }

            var texture = new GorgonTexture2D(graphics, newInfo);
            GorgonDepthStencil2DView result = texture.GetDepthStencilView(depthStencilFormat, flags: viewFlags);

            result.OwnsResource = true;

            return(result);
        }