예제 #1
0
        /// <summary>
        /// Creates a new <see cref="Pipeline"/> object.
        /// </summary>
        /// <param name="description">The desired properties of the created object.</param>
        /// <returns>A new <see cref="Pipeline"/> which, when bound to a CommandList, is used to dispatch draw commands.</returns>
        public Pipeline CreateGraphicsPipeline(ref GraphicsPipelineDescription description)
        {
#if VALIDATE_USAGE
            if (!description.RasterizerState.DepthClipEnabled && !Features.DepthClipDisable)
            {
                throw new VeldridException(
                          "RasterizerState.DepthClipEnabled must be true if GraphicsDeviceFeatures.DepthClipDisable is not supported.");
            }
            if (description.RasterizerState.FillMode == PolygonFillMode.Wireframe && !Features.FillModeWireframe)
            {
                throw new VeldridException(
                          "PolygonFillMode.Wireframe requires GraphicsDeviceFeatures.FillModeWireframe.");
            }
            if (!Features.IndependentBlend)
            {
                if (description.BlendState.AttachmentStates.Length > 0)
                {
                    BlendAttachmentDescription attachmentState = description.BlendState.AttachmentStates[0];
                    for (int i = 1; i < description.BlendState.AttachmentStates.Length; i++)
                    {
                        if (!attachmentState.Equals(description.BlendState.AttachmentStates[i]))
                        {
                            throw new VeldridException(
                                      $"If GraphcsDeviceFeatures.IndependentBlend is false, then all members of BlendState.AttachmentStates must be equal.");
                        }
                    }
                }
            }
            foreach (VertexLayoutDescription layoutDesc in description.ShaderSet.VertexLayouts)
            {
                bool hasExplicitLayout = false;
                uint minOffset         = 0;
                foreach (VertexElementDescription elementDesc in layoutDesc.Elements)
                {
                    if (hasExplicitLayout && elementDesc.Offset == 0)
                    {
                        throw new VeldridException(
                                  $"If any vertex element has an explicit offset, then all elements must have an explicit offset.");
                    }

                    if (elementDesc.Offset != 0 && elementDesc.Offset < minOffset)
                    {
                        throw new VeldridException(
                                  $"Vertex element \"{elementDesc.Name}\" has an explicit offset which overlaps with the previous element.");
                    }

                    minOffset          = elementDesc.Offset + FormatHelpers.GetSizeInBytes(elementDesc.Format);
                    hasExplicitLayout |= elementDesc.Offset != 0;
                }

                if (minOffset > layoutDesc.Stride)
                {
                    throw new VeldridException(
                              $"The vertex layout's stride ({layoutDesc.Stride}) is less than the full size of the vertex ({minOffset})");
                }
            }
#endif
            return(CreateGraphicsPipelineCore(ref description));
        }
        /// <summary>
        /// Constructs a new VertexLayoutDescription. The stride is assumed to be the sum of the size of all elements.
        /// </summary>
        /// <param name="elements">An array of <see cref="VertexElementDescription"/> objects, each describing a single element
        /// of vertex data.</param>
        public VertexLayoutDescription(params VertexElementDescription[] elements)
        {
            Elements = elements;
            uint computedStride = 0;

            for (int i = 0; i < elements.Length; i++)
            {
                computedStride += FormatHelpers.GetSizeInBytes(elements[i].Format);
            }

            Stride = computedStride;
        }
예제 #3
0
파일: Util.cs 프로젝트: leafi/veldrid
        internal static uint ComputeMipOffset(Texture tex, uint mipLevel)
        {
            uint offset = 0;

            for (uint level = 0; level < mipLevel; level++)
            {
                Util.GetMipDimensions(tex, level, out uint mipWidth, out uint mipHeight, out uint mipDepth);
                offset += mipWidth * mipHeight * mipDepth * FormatHelpers.GetSizeInBytes(tex.Format);
            }

            return(offset);
        }
예제 #4
0
파일: Util.cs 프로젝트: leafi/veldrid
        internal static uint ComputeArrayLayerOffset(Texture tex, uint arrayLayer)
        {
            if (arrayLayer == 0)
            {
                return(0);
            }

            uint layerPitch = 0;

            for (uint level = 0; level < tex.MipLevels; level++)
            {
                Util.GetMipDimensions(tex, level, out uint mipWidth, out uint mipHeight, out uint mipDepth);
                layerPitch += mipWidth * mipHeight * mipDepth * FormatHelpers.GetSizeInBytes(tex.Format);
            }

            return(layerPitch * arrayLayer);
        }
예제 #5
0
        /// <summary>
        /// Constructs a new VertexLayoutDescription. The stride is assumed to be the sum of the size of all elements.
        /// </summary>
        /// <param name="elements">An array of <see cref="VertexElementDescription"/> objects, each describing a single element
        /// of vertex data.</param>
        public VertexLayoutDescription(params VertexElementDescription[] elements)
        {
            Elements = elements;
            uint computedStride = 0;

            for (int i = 0; i < elements.Length; i++)
            {
                uint elementSize = FormatHelpers.GetSizeInBytes(elements[i].Format);
                if (elements[i].Offset != 0)
                {
                    computedStride = elements[i].Offset + elementSize;
                }
                else
                {
                    computedStride += elementSize;
                }
            }

            Stride           = computedStride;
            InstanceStepRate = 0;
        }
예제 #6
0
        public static unsafe void CopyTextureRegion(
            void *src,
            uint srcX, uint srcY, uint srcZ,
            uint srcRowPitch,
            uint srcDepthPitch,
            void *dst,
            uint dstX, uint dstY, uint dstZ,
            uint dstRowPitch,
            uint dstDepthPitch,
            uint width,
            uint height,
            uint depth,
            PixelFormat format)
        {
            uint blockSize        = FormatHelpers.IsCompressedFormat(format) ? 4u : 1u;
            uint blockSizeInBytes = blockSize > 1 ? FormatHelpers.GetBlockSizeInBytes(format) : FormatHelpers.GetSizeInBytes(format);
            uint compressedSrcX   = srcX / blockSize;
            uint compressedSrcY   = srcY / blockSize;
            uint compressedDstX   = dstX / blockSize;
            uint compressedDstY   = dstY / blockSize;
            uint numRows          = FormatHelpers.GetNumRows(height, format);
            uint rowSize          = width / blockSize * blockSizeInBytes;

            if (srcRowPitch == dstRowPitch && srcDepthPitch == dstDepthPitch)
            {
                uint totalCopySize = depth * srcDepthPitch;
                Buffer.MemoryCopy(
                    src,
                    dst,
                    totalCopySize,
                    totalCopySize);
            }
            else
            {
                for (uint zz = 0; zz < depth; zz++)
                {
                    for (uint yy = 0; yy < numRows; yy++)
                    {
                        byte *rowCopyDst = (byte *)dst
                                           + dstDepthPitch * (zz + dstZ)
                                           + dstRowPitch * (yy + compressedDstY)
                                           + blockSizeInBytes * compressedDstX;

                        byte *rowCopySrc = (byte *)src
                                           + srcDepthPitch * (zz + srcZ)
                                           + srcRowPitch * (yy + compressedSrcY)
                                           + blockSizeInBytes * compressedSrcX;

                        Unsafe.CopyBlock(rowCopyDst, rowCopySrc, rowSize);
                    }
                }
            }
        }