public void UpdateVertexAttribute(ID3D11Device device, ID3D11DeviceContext context, Semantics semantic, Memory <byte> bytes) { var buffer = m_vertexBufferMap[semantic]; if (MemoryMarshal.TryGetArray(bytes, out ArraySegment <byte> segment)) { using (var pin = PinPtr.Create(segment)) { var box = new D3D11_BOX { }; context.UpdateSubresource(buffer.Buffer, 0, ref box, pin.Ptr, 0, 0); } } }
private protected unsafe override void UpdateBufferCore(DeviceBuffer buffer, uint bufferOffsetInBytes, IntPtr source, uint sizeInBytes) { D3D11Buffer d3dBuffer = Util.AssertSubtype <DeviceBuffer, D3D11Buffer>(buffer); if (sizeInBytes == 0) { return; } bool isDynamic = (buffer.Usage & BufferUsage.Dynamic) == BufferUsage.Dynamic; bool isStaging = (buffer.Usage & BufferUsage.Staging) == BufferUsage.Staging; bool isUniformBuffer = (buffer.Usage & BufferUsage.UniformBuffer) == BufferUsage.UniformBuffer; bool updateFullBuffer = bufferOffsetInBytes == 0 && sizeInBytes == buffer.SizeInBytes; bool useUpdateSubresource = (!isDynamic && !isStaging) && (!isUniformBuffer || updateFullBuffer); bool useMap = (isDynamic && updateFullBuffer) || isStaging; if (useUpdateSubresource) { Box?subregion = new Box() { Left = (int)bufferOffsetInBytes, Right = (int)(sizeInBytes + bufferOffsetInBytes), Bottom = 1, Back = 1 }; if (isUniformBuffer) { subregion = null; } lock (_immediateContextLock) { _immediateContext.UpdateSubresource(d3dBuffer.Buffer, 0, subregion, source, 0, 0); } } else if (useMap) { MappedResource mr = MapCore(buffer, MapMode.Write, 0); if (sizeInBytes < 1024) { Unsafe.CopyBlock((byte *)mr.Data + bufferOffsetInBytes, source.ToPointer(), sizeInBytes); } else { Buffer.MemoryCopy( source.ToPointer(), (byte *)mr.Data + bufferOffsetInBytes, buffer.SizeInBytes, sizeInBytes); } UnmapCore(buffer, 0); } else { D3D11Buffer staging = GetFreeStagingBuffer(sizeInBytes); UpdateBuffer(staging, 0, source, sizeInBytes); Box sourceRegion = new Box(0, 0, 0, (int)sizeInBytes, 1, 1); lock (_immediateContextLock) { _immediateContext.CopySubresourceRegion( d3dBuffer.Buffer, 0, (int)bufferOffsetInBytes, 0, 0, staging.Buffer, 0, sourceRegion); } lock (_stagingResourcesLock) { _availableStagingBuffers.Add(staging); } } }