示例#1
0
        private void DrawBatchPerTextureAndPass(ElementInfo[] sprites, int offset, int count)
        {
            while (count > 0)
            {
                // How many index/vertex do we want to draw?
                var indexCount  = 0;
                var vertexCount = 0;
                var batchSize   = 0;

                while (batchSize < count)
                {
                    var spriteIndex = offset + batchSize;

                    // How many sprites does the D3D vertex buffer have room for?
                    var remainingVertexSpace = ResourceContext.VertexCount - ResourceContext.VertexBufferPosition - vertexCount;
                    var remainingIndexSpace  = ResourceContext.IndexCount - ResourceContext.IndexBufferPosition - indexCount;

                    // if there is not enough place let for either the indices or vertices of the current element...,
                    if (sprites[spriteIndex].IndexCount > remainingIndexSpace || sprites[spriteIndex].VertexCount > remainingVertexSpace)
                    {
                        // if we haven't started the current batch yet, we restart at the beginning of the buffers.
                        if (batchSize == 0)
                        {
                            ResourceContext.VertexBufferPosition = 0;
                            ResourceContext.IndexBufferPosition  = 0;
                            continue;
                        }

                        // else we perform the draw call and  batch remaining elements in next draw call.
                        break;
                    }

                    ++batchSize;
                    vertexCount += sprites[spriteIndex].VertexCount;
                    indexCount  += sprites[spriteIndex].IndexCount;
                }

                // Sets the data directly to the buffer in memory
                var offsetVertexInBytes = ResourceContext.VertexBufferPosition * vertexStructSize;
                var offsetIndexInBytes  = ResourceContext.IndexBufferPosition * indexStructSize;

                var noOverwriteVertex = ResourceContext.VertexBufferPosition == 0 ? MapMode.WriteDiscard : MapMode.WriteNoOverwrite;
                var noOverwriteIndex  = ResourceContext.IndexBufferPosition == 0 ? MapMode.WriteDiscard : MapMode.WriteNoOverwrite;

                // ------------------------------------------------------------------------------------------------------------
                // CAUTION: Performance problem under x64 resolved by this special codepath:
                // For some unknown reasons, It seems that writing directly to the pointer returned by the MapSubresource is
                // extremely inefficient using x64 but using a temporary buffer and performing a mempcy to the locked region
                // seems to be running at the same speed than x86
                // ------------------------------------------------------------------------------------------------------------
                // TODO Check again why we need this code
                //if (IntPtr.Size == 8)
                //{
                //    if (x64TempBuffer == null)
                //    {
                //        x64TempBuffer = ToDispose(new DataBuffer(Utilities.SizeOf<VertexPositionColorTexture>() * MaxBatchSize * VerticesPerSprite));
                //    }

                //    // Perform the update of all vertices on a temporary buffer
                //    var texturePtr = (VertexPositionColorTexture*)x64TempBuffer.DataPointer;
                //    for (int i = 0; i < batchSize; i++)
                //    {
                //        UpdateBufferValuesFromElementInfo(ref sprites[offset + i], ref texturePtr, deltaX, deltaY);
                //    }

                //    // Then copy this buffer in one shot
                //    resourceContext.VertexBuffer.SetData(GraphicsDevice, new DataPointer(x64TempBuffer.DataPointer, batchSize * VerticesPerSprite * Utilities.SizeOf<VertexPositionColorTexture>()), offsetInBytes, noOverwrite);
                //}
                //else
                {
                    var mappedIndices  = new MappedResource();
                    var mappedVertices = GraphicsDevice.MapSubresource(ResourceContext.VertexBuffer, 0, noOverwriteVertex, false, offsetVertexInBytes, vertexCount * vertexStructSize);
                    if (ResourceContext.IsIndexBufferDynamic)
                    {
                        mappedIndices = GraphicsDevice.MapSubresource(ResourceContext.IndexBuffer, 0, noOverwriteIndex, false, offsetIndexInBytes, indexCount * indexStructSize);
                    }

                    var vertexPointer = mappedVertices.DataBox.DataPointer;
                    var indexPointer  = mappedIndices.DataBox.DataPointer;

                    for (var i = 0; i < batchSize; i++)
                    {
                        var spriteIndex = offset + i;

                        UpdateBufferValuesFromElementInfo(ref sprites[spriteIndex], vertexPointer, indexPointer, ResourceContext.VertexBufferPosition);

                        ResourceContext.VertexBufferPosition += sprites[spriteIndex].VertexCount;
                        vertexPointer += vertexStructSize * sprites[spriteIndex].VertexCount;
                        indexPointer  += indexStructSize * sprites[spriteIndex].IndexCount;
                    }

                    GraphicsDevice.UnmapSubresource(mappedVertices);
                    if (ResourceContext.IsIndexBufferDynamic)
                    {
                        GraphicsDevice.UnmapSubresource(mappedIndices);
                    }
                }

                // Draw from the specified index
                GraphicsDevice.DrawIndexed(PrimitiveType.TriangleList, indexCount, ResourceContext.IndexBufferPosition);

                // Update position, offset and remaining count
                ResourceContext.IndexBufferPosition += indexCount;
                offset += batchSize;
                count  -= batchSize;
            }
        }
 public void UnmapSubresource(MappedResource unmapped)
 {
     NativeDeviceContext.UnmapSubresource(unmapped.Resource.NativeResource, unmapped.SubResourceIndex);
 }
示例#3
0
 public void UnmapSubresource(MappedResource unmapped)
 {
     NativeDeviceContext.UnmapSubresource(unmapped.Resource.NativeResource, unmapped.SubResourceIndex);
 }