protected override void UnmapCore(MappableResource resource, uint subresource) { MappedResourceCacheKey key = new MappedResourceCacheKey(resource, subresource); bool commitUnmap; lock (_mappedResourceLock) { if (!_mappedResources.TryGetValue(key, out MappedResourceInfo info)) { throw new VeldridException($"The given resource ({resource}) is not mapped."); } info.RefCount -= 1; commitUnmap = info.RefCount == 0; if (commitUnmap) { lock (_immediateContextLock) { if (resource is D3D11Buffer buffer) { _immediateContext.Unmap(buffer.Buffer, 0); } else { D3D11Texture texture = Util.AssertSubtype <MappableResource, D3D11Texture>(resource); _immediateContext.Unmap(texture.DeviceTexture, (int)subresource); } bool result = _mappedResources.Remove(key); Debug.Assert(result); } } } }
private void UpdateBBox(ID3D11Device InDevice, ID3D11DeviceContext InDContext) { // Update vertex buffer VertexLayouts.BasicLayout.Vertex[] BBoxVertices = new VertexLayouts.BasicLayout.Vertex[Objects.Count * 8]; int CurrentBBoxIndex = 0; foreach (RenderBoundingBox BBox in Objects.Values) { VertexLayouts.BasicLayout.Vertex[] Cached = BBox.GetTransformVertices(); System.Array.Copy(Cached, 0, BBoxVertices, CurrentBBoxIndex * Cached.Length, Cached.Length); CurrentBBoxIndex++; } // Update index buffer uint[] BBoxIndices = new uint[Objects.Count * 24]; CurrentBBoxIndex = 0; foreach (RenderBoundingBox BBox in Objects.Values) { uint[] CopiedIndices = new uint[BBox.Indices.Length]; for (int i = 0; i < CopiedIndices.Length; i++) { int BBoxOffset = (CurrentBBoxIndex * 8); CopiedIndices[i] = (ushort)(BBox.Indices[i] + BBoxOffset); } System.Array.Copy(CopiedIndices, 0, BBoxIndices, CurrentBBoxIndex * BBox.Indices.Length, BBox.Indices.Length); CurrentBBoxIndex++; } SizeToRender = Objects.Count * 24; if (VertexBuffer == null && IndexBuffer == null) { VertexBuffer = InDevice.CreateBuffer(BindFlags.VertexBuffer, BBoxVertices, 0, ResourceUsage.Dynamic, CpuAccessFlags.Write); IndexBuffer = InDevice.CreateBuffer(BindFlags.IndexBuffer, BBoxIndices, 0, ResourceUsage.Dynamic, CpuAccessFlags.Write); } else { // TODO: Templatize this MappedSubresource mappedResource = InDContext.Map(VertexBuffer, MapMode.WriteDiscard, MapFlags.None); unsafe { UnsafeUtilities.Write(mappedResource.DataPointer, BBoxVertices); } InDContext.Unmap(VertexBuffer); mappedResource = InDContext.Map(IndexBuffer, MapMode.WriteDiscard, MapFlags.None); unsafe { UnsafeUtilities.Write(mappedResource.DataPointer, BBoxIndices); } InDContext.Unmap(IndexBuffer); } }
private void UpdateLines(ID3D11Device InDevice, ID3D11DeviceContext InDContext) { // Update buffers List <VertexLayouts.BasicLayout.Vertex> TempLineVertices = new List <VertexLayouts.BasicLayout.Vertex>(); List <ushort> TempLineIndices = new List <ushort>(); int CurrentVertexCount = 0; foreach (RenderLine Line in Objects.Values) { TempLineVertices.AddRange(Line.GetVertices); ushort[] CopiedIndices = Line.GetStrippedIndices; for (uint x = 0; x < CopiedIndices.Length; x++) { CopiedIndices[x] += (ushort)(CurrentVertexCount); } TempLineIndices.AddRange(CopiedIndices.ToList()); TempLineIndices.Add(ushort.MaxValue); CurrentVertexCount = TempLineVertices.Count; } SizeToRender = TempLineIndices.Count; if (VertexBuffer == null && IndexBuffer == null) { VertexBuffer = InDevice.CreateBuffer(BindFlags.VertexBuffer, TempLineVertices.ToArray(), 0, ResourceUsage.Dynamic, CpuAccessFlags.Write); IndexBuffer = InDevice.CreateBuffer(BindFlags.IndexBuffer, TempLineIndices.ToArray(), 0, ResourceUsage.Dynamic, CpuAccessFlags.Write); } else { // TODO: Templatize this MappedSubresource mappedResource = InDContext.Map(VertexBuffer, MapMode.WriteDiscard, MapFlags.None); unsafe { UnsafeUtilities.Write(mappedResource.DataPointer, TempLineVertices.ToArray()); } InDContext.Unmap(VertexBuffer); mappedResource = InDContext.Map(IndexBuffer, MapMode.WriteDiscard, MapFlags.None); unsafe { UnsafeUtilities.Write(mappedResource.DataPointer, TempLineIndices.ToArray()); } InDContext.Unmap(IndexBuffer); } }
unsafe public static void UpdateVertexBuffer <T>(ID3D11DeviceContext context, ID3D11Buffer buffer, int slot, T data) where T : struct { MappedSubresource mappedResource = context.Map(buffer, MapMode.WriteDiscard, MapFlags.None); Unsafe.Write((void *)mappedResource.DataPointer, data); context.Unmap(buffer); context.VSSetConstantBuffer(slot, buffer); }
public override void UpdateBuffers(ID3D11Device device, ID3D11DeviceContext deviceContext) { if (bIsUpdatedNeeded) { MappedSubresource mappedResource = deviceContext.Map(vertexBuffer, MapMode.WriteDiscard, MapFlags.None); unsafe { UnsafeUtilities.Write(mappedResource.DataPointer, vertices); } deviceContext.Unmap(vertexBuffer, 0); bIsUpdatedNeeded = false; } }
public static void Unmap(this ID3D11DeviceContext context, ID3D11Resource resource, int subResource) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (resource == null) { throw new ArgumentNullException(nameof(resource)); } context.Unmap(resource, (uint)subResource); }
public void Render(ImDrawDataPtr data) { // Avoid rendering when minimized if (data.DisplaySize.X <= 0.0f || data.DisplaySize.Y <= 0.0f) { return; } ID3D11DeviceContext ctx = deviceContext; if (vertexBuffer == null || vertexBufferSize < data.TotalVtxCount) { vertexBuffer?.Release(); vertexBufferSize = data.TotalVtxCount + 5000; BufferDescription desc = new BufferDescription(); desc.Usage = Vortice.Direct3D11.Usage.Dynamic; desc.SizeInBytes = vertexBufferSize * sizeof(ImDrawVert); desc.BindFlags = BindFlags.VertexBuffer; desc.CpuAccessFlags = CpuAccessFlags.Write; vertexBuffer = device.CreateBuffer(desc); } if (indexBuffer == null || indexBufferSize < data.TotalIdxCount) { indexBuffer?.Release(); indexBufferSize = data.TotalIdxCount + 10000; BufferDescription desc = new BufferDescription(); desc.Usage = Vortice.Direct3D11.Usage.Dynamic; desc.SizeInBytes = indexBufferSize * sizeof(ImDrawIdx); desc.BindFlags = BindFlags.IndexBuffer; desc.CpuAccessFlags = CpuAccessFlags.Write; indexBuffer = device.CreateBuffer(desc); } // Upload vertex/index data into a single contiguous GPU buffer var vertexResource = ctx.Map(vertexBuffer, 0, MapMode.WriteDiscard, Vortice.Direct3D11.MapFlags.None); var indexResource = ctx.Map(indexBuffer, 0, MapMode.WriteDiscard, Vortice.Direct3D11.MapFlags.None); var vertexResourcePointer = (ImDrawVert *)vertexResource.DataPointer; var indexResourcePointer = (ImDrawIdx *)indexResource.DataPointer; for (int n = 0; n < data.CmdListsCount; n++) { var cmdlList = data.CmdListsRange[n]; var vertBytes = cmdlList.VtxBuffer.Size * sizeof(ImDrawVert); Buffer.MemoryCopy((void *)cmdlList.VtxBuffer.Data, vertexResourcePointer, vertBytes, vertBytes); var idxBytes = cmdlList.IdxBuffer.Size * sizeof(ImDrawIdx); Buffer.MemoryCopy((void *)cmdlList.IdxBuffer.Data, indexResourcePointer, idxBytes, idxBytes); vertexResourcePointer += cmdlList.VtxBuffer.Size; indexResourcePointer += cmdlList.IdxBuffer.Size; } ctx.Unmap(vertexBuffer, 0); ctx.Unmap(indexBuffer, 0); // Setup orthographic projection matrix into our constant buffer // Our visible imgui space lies from draw_data.DisplayPos (top left) to draw_data.DisplayPos+data_data.DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps. var constResource = ctx.Map(constantBuffer, 0, MapMode.WriteDiscard, Vortice.Direct3D11.MapFlags.None); var span = constResource.AsSpan <float>(VertexConstantBufferSize); float L = data.DisplayPos.X; float R = data.DisplayPos.X + data.DisplaySize.X; float T = data.DisplayPos.Y; float B = data.DisplayPos.Y + data.DisplaySize.Y; float[] mvp = { 2.0f / (R - L), 0.0f, 0.0f, 0.0f, 0.0f, 2.0f / (T - B), 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, (R + L) / (L - R), (T + B) / (B - T), 0.5f, 1.0f, }; mvp.CopyTo(span); ctx.Unmap(constantBuffer, 0); SetupRenderState(data, ctx); // Render command lists // (Because we merged all buffers into a single one, we maintain our own offset into them) int global_idx_offset = 0; int global_vtx_offset = 0; Vector2 clip_off = data.DisplayPos; for (int n = 0; n < data.CmdListsCount; n++) { var cmdList = data.CmdListsRange[n]; for (int i = 0; i < cmdList.CmdBuffer.Size; i++) { var cmd = cmdList.CmdBuffer[i]; if (cmd.UserCallback != IntPtr.Zero) { throw new NotImplementedException("user callbacks not implemented"); } else { var rect = new Rect((int)(cmd.ClipRect.X - clip_off.X), (int)(cmd.ClipRect.Y - clip_off.Y), (int)(cmd.ClipRect.Z - clip_off.X), (int)(cmd.ClipRect.W - clip_off.Y)); ctx.RSSetScissorRects(rect); textureResources.TryGetValue(cmd.TextureId, out var texture); if (texture != null) { ctx.PSSetShaderResources(0, texture); } ctx.DrawIndexed((int)cmd.ElemCount, (int)(cmd.IdxOffset + global_idx_offset), (int)(cmd.VtxOffset + global_vtx_offset)); } } global_idx_offset += cmdList.IdxBuffer.Size; global_vtx_offset += cmdList.VtxBuffer.Size; } }
public void Unmap(IResource resource) { _context.Unmap(resource.NativeHandle); }