A GPU resource mapped for CPU access. This is returned by using GraphicsDevice.MapSubresource
Example #1
0
 public void Unmap()
 {
     if (UseBufferOffsets && mappedConstantBuffer.Resource != null)
     {
         using (new DefaultCommandListLock(commandList))
         {
             commandList.UnmapSubresource(mappedConstantBuffer);
             mappedConstantBuffer = new MappedResource();
         }
     }
 }
Example #2
0
 public void Map(CommandList commandList)
 {
     if (UseBufferOffsets)
     {
         using (new DefaultCommandListLock(commandList))
         {
             this.commandList     = commandList;
             mappedConstantBuffer = commandList.MapSubresource(constantBuffer, 0, MapMode.WriteNoOverwrite);
             Data = mappedConstantBuffer.DataBox.DataPointer;
         }
     }
 }
Example #3
0
        /// <summary>
        /// Begins text rendering (swaps and maps the vertex buffer to write to).
        /// </summary>
        /// <param name="graphicsContext">The current GraphicsContext.</param>
        public void End([NotNull] GraphicsContext graphicsContext)
        {
            if (graphicsContext == null)
            {
                throw new ArgumentNullException(nameof(graphicsContext));
            }

            // Reallocate buffers if max number of characters is exceeded
            if (charsToRenderCount > maxCharacterCount)
            {
                maxCharacterCount = (int)(1.5f * charsToRenderCount);
                Initialize(graphicsContext, maxCharacterCount);
            }

            // Set the rendering parameters
            simpleEffect.Parameters.Set(TexturingKeys.Texture0, DebugSpriteFont);
            simpleEffect.Parameters.Set(SpriteEffectKeys.Color, TextColor);

            // Swap vertex buffer
            activeVertexBufferIndex = ++activeVertexBufferIndex >= VertexBufferCount ? 0 : activeVertexBufferIndex;

            // Map the vertex buffer to write to
            mappedVertexBuffer        = graphicsContext.CommandList.MapSubresource(vertexBuffers[activeVertexBufferIndex], 0, MapMode.WriteDiscard);
            mappedVertexBufferPointer = mappedVertexBuffer.DataBox.DataPointer;

            unsafe
            {
                // Clear buffer first (because of the buffer mapping mode used)
                Utilities.ClearMemory(mappedVertexBufferPointer, 0x0, VertexBufferLength * sizeof(VertexPositionNormalTexture));

                charsToRenderCount = 0;

                //Draw the strings
                var constantInfos = new RectangleF(GlyphWidth, GlyphHeight, DebugSpriteWidth, DebugSpriteHeight);
                foreach (var textInfo in stringsToDraw)
                {
                    var textLength        = textInfo.Text.Length;
                    var textLengthPointer = new IntPtr(&textLength);

                    Native.NativeInvoke.xnGraphicsFastTextRendererGenerateVertices(constantInfos, textInfo.RenderingInfo, textInfo.Text, out textLengthPointer, out mappedVertexBufferPointer);

                    charsToRenderCount += *(int *)textLengthPointer.ToPointer();
                }
            }

            // Unmap the vertex buffer
            graphicsContext.CommandList.UnmapSubresource(mappedVertexBuffer);
            mappedVertexBufferPointer = IntPtr.Zero;

            // Update pipeline state
            pipelineState.State.SetDefaults();
            pipelineState.State.RootSignature     = simpleEffect.RootSignature;
            pipelineState.State.EffectBytecode    = simpleEffect.Effect.Bytecode;
            pipelineState.State.DepthStencilState = DepthStencilStates.None;
            pipelineState.State.BlendState        = BlendStates.AlphaBlend;
            pipelineState.State.Output.CaptureState(graphicsContext.CommandList);
            pipelineState.State.InputElements = inputElementDescriptions[activeVertexBufferIndex];
            pipelineState.Update();

            graphicsContext.CommandList.SetPipelineState(pipelineState.CurrentState);

            // Update effect
            simpleEffect.UpdateEffect(graphicsContext.CommandList.GraphicsDevice);
            simpleEffect.Apply(graphicsContext);

            // Bind and draw
            graphicsContext.CommandList.SetVertexBuffer(0, vertexBuffersBinding[activeVertexBufferIndex].Buffer, vertexBuffersBinding[activeVertexBufferIndex].Offset, vertexBuffersBinding[activeVertexBufferIndex].Stride);
            graphicsContext.CommandList.SetIndexBuffer(indexBufferBinding.Buffer, 0, indexBufferBinding.Is32Bit);

            graphicsContext.CommandList.DrawIndexed(charsToRenderCount * 6);
        }
Example #4
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;
                    ref var spriteElementInfo = ref sprites[spriteIndex];

                    // 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 left for either the indices or vertices of the current element...,
                    if (spriteElementInfo.IndexCount > remainingIndexSpace || spriteElementInfo.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 += spriteElementInfo.VertexCount;
                    indexCount  += spriteElementInfo.IndexCount;
                }

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

                if (ResourceContext.VertexBufferPosition == 0)
                {
                    if (ResourceContext.VertexBuffer != null)
                    {
                        GraphicsContext.Allocator.ReleaseReference(ResourceContext.VertexBuffer);
                    }
                    ResourceContext.VertexBuffer = GraphicsContext.Allocator.GetTemporaryBuffer(new BufferDescription(ResourceContext.VertexCount * vertexStructSize, BufferFlags.VertexBuffer, GraphicsResourceUsage.Dynamic));
                    GraphicsContext.CommandList.SetVertexBuffer(0, ResourceContext.VertexBuffer, 0, vertexStructSize);
                }

                if (ResourceContext.IsIndexBufferDynamic && ResourceContext.IndexBufferPosition == 0)
                {
                    if (ResourceContext.IndexBuffer != null)
                    {
                        GraphicsContext.Allocator.ReleaseReference(ResourceContext.IndexBuffer);
                    }
                    ResourceContext.IndexBuffer = GraphicsContext.Allocator.GetTemporaryBuffer(new BufferDescription(ResourceContext.IndexCount * indexStructSize, BufferFlags.IndexBuffer, GraphicsResourceUsage.Dynamic));
                    GraphicsContext.CommandList.SetIndexBuffer(ResourceContext.IndexBuffer, 0, indexStructSize == sizeof(int));
                }

                // ------------------------------------------------------------------------------------------------------------
                // 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 = GraphicsContext.CommandList.MapSubresource(ResourceContext.VertexBuffer, 0, MapMode.WriteNoOverwrite, false, offsetVertexInBytes, vertexCount * vertexStructSize);
                    if (ResourceContext.IsIndexBufferDynamic)
                    {
                        mappedIndices = GraphicsContext.CommandList.MapSubresource(ResourceContext.IndexBuffer, 0, MapMode.WriteNoOverwrite, 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;
                        ref var spriteElementInfo = ref sprites[spriteIndex];

                        UpdateBufferValuesFromElementInfo(ref spriteElementInfo, vertexPointer, indexPointer, ResourceContext.VertexBufferPosition);

                        ResourceContext.VertexBufferPosition += spriteElementInfo.VertexCount;
                        vertexPointer += vertexStructSize * spriteElementInfo.VertexCount;
                        indexPointer  += indexStructSize * spriteElementInfo.IndexCount;
                    }

                    GraphicsContext.CommandList.UnmapSubresource(mappedVertices);
                    if (ResourceContext.IsIndexBufferDynamic)
                    {
                        GraphicsContext.CommandList.UnmapSubresource(mappedIndices);
                    }
                }
Example #5
0
 // TODO GRAPHICS REFACTOR what should we do with this?
 public void UnmapSubresource(MappedResource unmapped)
 {
     NativeDeviceContext.UnmapSubresource(unmapped.Resource.NativeResource, unmapped.SubResourceIndex);
 }
Example #6
0
 /// <summary>
 /// Unmap <param name="mapped"/> resource.
 /// </summary>
 /// <param name="mapped">The mapped resource.</param>
 public void UnmapSubresource(MappedResource mapped)
 {
     NullHelper.ToImplement();
 }