public void Unmap() { if (useBufferOffsets && mappedConstantBuffer.Resource != null) { using (new DefaultCommandListLock(commandList)) { commandList.UnmapSubresource(mappedConstantBuffer); mappedConstantBuffer = new MappedResource(); } } }
/// <summary> /// Begins text rendering (swaps and maps the vertex buffer to write to). /// </summary> /// <param name="graphicsContext">The current GraphicsContext.</param> public void Begin([NotNull] GraphicsContext graphicsContext) { // Swap vertex buffer activeVertexBufferIndex = activeVertexBufferIndex == 0 ? 1 : 0; charsToRenderCount = 0; // Map the vertex buffer to write to mappedVertexBuffer = graphicsContext.CommandList.MapSubresource(vertexBuffers[activeVertexBufferIndex], 0, MapMode.WriteDiscard); mappedVertexBufferPointer = mappedVertexBuffer.DataBox.DataPointer; }
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; } } }
/// <summary> /// Begins text rendering (swaps and maps the vertex buffer to write to). /// </summary> /// <param name="graphicsContext">The current GraphicsContext.</param> public void Begin([NotNull] GraphicsContext graphicsContext) { // Swap vertex buffer activeVertexBufferIndex = ++activeVertexBufferIndex >= VertexBufferCount ? 0 : activeVertexBufferIndex; charsToRenderCount = 0; // 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)); } }
// TODO GRAPHICS REFACTOR what should we do with this? public void UnmapSubresource(MappedResource unmapped) { if (unmapped.UploadResource != null) { // Copy back var buffer = unmapped.Resource as Buffer; if (buffer != null) { NativeCommandList.ResourceBarrierTransition(buffer.NativeResource, buffer.NativeResourceState, ResourceStates.CopyDestination); NativeCommandList.CopyBufferRegion(buffer.NativeResource, unmapped.OffsetInBytes, unmapped.UploadResource, unmapped.UploadOffset, unmapped.SizeInBytes); NativeCommandList.ResourceBarrierTransition(buffer.NativeResource, ResourceStates.CopyDestination, buffer.NativeResourceState); } } else { unmapped.Resource.NativeResource.Unmap(unmapped.SubResourceIndex); } }
public void UnmapSubresource(MappedResource unmapped) { NativeDeviceContext.UnmapSubresource(unmapped.Resource.NativeResource, unmapped.SubResourceIndex); }
/// <summary> /// Unmap <param name="mapped"/> resource. /// </summary> /// <param name="mapped">The mapped resource.</param> public void UnmapSubresource(MappedResource mapped) { NullHelper.ToImplement(); }
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; 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; UpdateBufferValuesFromElementInfo(ref sprites[spriteIndex], vertexPointer, indexPointer, ResourceContext.VertexBufferPosition); ResourceContext.VertexBufferPosition += sprites[spriteIndex].VertexCount; vertexPointer += vertexStructSize * sprites[spriteIndex].VertexCount; indexPointer += indexStructSize * sprites[spriteIndex].IndexCount; } GraphicsContext.CommandList.UnmapSubresource(mappedVertices); if (ResourceContext.IsIndexBufferDynamic) { GraphicsContext.CommandList.UnmapSubresource(mappedIndices); } } // Draw from the specified index GraphicsContext.CommandList.DrawIndexed(indexCount, ResourceContext.IndexBufferPosition); // Update position, offset and remaining count ResourceContext.IndexBufferPosition += indexCount; offset += batchSize; count -= batchSize; } }
// TODO GRAPHICS REFACTOR what should we do with this? public void UnmapSubresource(MappedResource unmapped) { NativeDeviceContext.UnmapSubresource(unmapped.Resource.NativeResource, unmapped.SubResourceIndex); }
// TODO GRAPHICS REFACTOR what should we do with this? public void UnmapSubresource(MappedResource unmapped) { unmapped.Resource.NativeResource.Unmap(unmapped.SubResourceIndex); }
public void UnmapSubresource(MappedResource unmapped) { #if DEBUG GraphicsDevice.EnsureContextActive(); #endif var texture = unmapped.Resource as Texture; if (texture != null) { if (texture.Description.Usage == GraphicsResourceUsage.Staging) { #if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES // unmapping on OpenGL ES 2 means doing nothing since the buffer is on the CPU memory if (!GraphicsDevice.IsOpenGLES2) #endif { GL.BindBuffer(BufferTarget.PixelPackBuffer, texture.PixelBufferObjectId); GL.UnmapBuffer(BufferTarget.PixelPackBuffer); GL.BindBuffer(BufferTarget.PixelPackBuffer, 0); } } #if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES else if (!GraphicsDevice.IsOpenGLES2 && texture.Description.Usage == GraphicsResourceUsage.Dynamic) #else else if (texture.Description.Usage == GraphicsResourceUsage.Dynamic) #endif { GL.BindBuffer(BufferTarget.PixelUnpackBuffer, unmapped.PixelBufferObjectId); GL.UnmapBuffer(BufferTarget.PixelUnpackBuffer); if (activeTexture != 0) { activeTexture = 0; GL.ActiveTexture(TextureUnit.Texture0); } GL.BindTexture(texture.TextureTarget, texture.TextureId); var mipLevel = unmapped.SubResourceIndex % texture.MipLevels; var arraySlice = unmapped.SubResourceIndex / texture.MipLevels; // Bind buffer to texture switch (texture.TextureTarget) { #if !SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES case TextureTarget.Texture1D: GL.TexSubImage1D(TextureTarget.Texture1D, mipLevel, 0, texture.Width, texture.TextureFormat, texture.TextureType, IntPtr.Zero); break; #endif case TextureTarget.Texture2D: GL.TexSubImage2D(TextureTarget2d.Texture2D, mipLevel, 0, 0, texture.Width, texture.Height, texture.TextureFormat, texture.TextureType, IntPtr.Zero); break; case TextureTarget.Texture2DArray: GL.TexSubImage3D(TextureTarget3d.Texture2DArray, mipLevel, 0, 0, arraySlice, texture.Width, texture.Height, 1, texture.TextureFormat, texture.TextureType, IntPtr.Zero); break; case TextureTarget.Texture3D: GL.TexSubImage3D(TextureTarget3d.Texture3D, mipLevel, 0, 0, 0, texture.Width, texture.Height, texture.Depth, texture.TextureFormat, texture.TextureType, IntPtr.Zero); break; case TextureTarget.TextureCubeMap: GL.TexSubImage2D(Texture.GetTextureTargetForDataSet2D(texture.TextureTarget, arraySlice), mipLevel, 0, 0, texture.Width, texture.Height, texture.TextureFormat, texture.TextureType, IntPtr.Zero); break; default: throw new NotSupportedException("Invalid texture target: " + texture.TextureTarget); } GL.BindTexture(texture.TextureTarget, 0); boundShaderResourceViews[0] = null; GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0); GL.DeleteBuffer(unmapped.PixelBufferObjectId); } else { throw new NotSupportedException("Not supported mapper operation for Usage: " + texture.Description.Usage); } } else { var buffer = unmapped.Resource as Buffer; if (buffer != null) { #if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES if (GraphicsDevice.IsOpenGLES2 || buffer.StagingData != IntPtr.Zero) #else if (buffer.StagingData != IntPtr.Zero) #endif { // Only buffer with StagingData (fake cbuffer) could be mapped if (buffer.StagingData == IntPtr.Zero) throw new InvalidOperationException(); // Is it a real buffer? (fake cbuffer have no real GPU counter-part in OpenGL ES 2.0 if (buffer.BufferId != 0) { //UnbindVertexArrayObject(); GL.BindBuffer(buffer.BufferTarget, buffer.BufferId); if (unmapped.OffsetInBytes == 0 && unmapped.SizeInBytes == buffer.SizeInBytes) GL.BufferData(buffer.BufferTarget, unmapped.SizeInBytes, unmapped.DataBox.DataPointer, buffer.BufferUsageHint); else GL.BufferSubData(buffer.BufferTarget, (IntPtr)unmapped.OffsetInBytes, (IntPtr)unmapped.SizeInBytes, unmapped.DataBox.DataPointer); } } else { //UnbindVertexArrayObject(); GL.BindBuffer(buffer.BufferTarget, buffer.BufferId); GL.UnmapBuffer(buffer.BufferTarget); } } else // neither texture nor buffer { Internal.Refactor.ThrowNotImplementedException("UnmapSubresource not implemented for type " + unmapped.Resource.GetType()); } } }