public DX11RWStructuredBuffer(int elementcount, int stride, IntPtr uav, IntPtr srv) { this.ElementCount = elementcount; this.Stride = stride; this.UAV = UnorderedAccessView.FromPointer(uav); //this.UAV.Dispose(); this.SRV = ShaderResourceView.FromPointer(srv); //this.SRV.Dispose(); }
public static void RenderDrawData(ImDrawDataPtr drawData) { // Avoid rendering when minimized if (drawData.DisplaySize.X <= 0 || drawData.DisplaySize.Y <= 0) { return; } if (!drawData.Valid || drawData.CmdListsCount == 0) { return; } //drawData.ScaleClipRects(ImGui.GetIO().DisplayFramebufferScale); // Create and grow vertex/index buffers if needed if (_vertexBuffer == null || _vertexBufferSize < drawData.TotalVtxCount) { _vertexBuffer?.Dispose(); _vertexBufferSize = drawData.TotalVtxCount + 5000; _vertexBuffer = new Buffer(_device, new BufferDescription { Usage = ResourceUsage.Dynamic, SizeInBytes = Unsafe.SizeOf <ImDrawVert>() * _vertexBufferSize, BindFlags = BindFlags.VertexBuffer, CpuAccessFlags = CpuAccessFlags.Write, OptionFlags = ResourceOptionFlags.None }); } if (_indexBuffer == null || _indexBufferSize < drawData.TotalIdxCount) { _indexBuffer?.Dispose(); _indexBufferSize = drawData.TotalIdxCount + 10000; _indexBuffer = new Buffer(_device, new BufferDescription { Usage = ResourceUsage.Dynamic, SizeInBytes = sizeof(ushort) * _indexBufferSize, // ImGui.NET doesn't provide an ImDrawIdx, but their sample uses ushort BindFlags = BindFlags.IndexBuffer, CpuAccessFlags = CpuAccessFlags.Write }); } // Upload vertex/index data into a single contiguous GPU buffer int vertexOffset = 0, indexOffset = 0; var vertexData = _deviceContext.MapSubresource(_vertexBuffer, 0, MapMode.WriteDiscard, MapFlags.None).DataPointer; var indexData = _deviceContext.MapSubresource(_indexBuffer, 0, MapMode.WriteDiscard, MapFlags.None).DataPointer; for (int n = 0; n < drawData.CmdListsCount; n++) { var cmdList = drawData.CmdListsRange[n]; unsafe { System.Buffer.MemoryCopy(cmdList.VtxBuffer.Data.ToPointer(), (ImDrawVert *)vertexData + vertexOffset, Unsafe.SizeOf <ImDrawVert>() * _vertexBufferSize, Unsafe.SizeOf <ImDrawVert>() * cmdList.VtxBuffer.Size); System.Buffer.MemoryCopy(cmdList.IdxBuffer.Data.ToPointer(), (ushort *)indexData + indexOffset, sizeof(ushort) * _indexBufferSize, sizeof(ushort) * cmdList.IdxBuffer.Size); vertexOffset += cmdList.VtxBuffer.Size; indexOffset += cmdList.IdxBuffer.Size; } } _deviceContext.UnmapSubresource(_vertexBuffer, 0); _deviceContext.UnmapSubresource(_indexBuffer, 0); // Setup orthographic projection matrix into our constant buffer // Our visible imgui space lies from drawData.DisplayPos (top left) to drawData.DisplayPos+drawData.DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps. var L = drawData.DisplayPos.X; var R = drawData.DisplayPos.X + drawData.DisplaySize.X; var T = drawData.DisplayPos.Y; var B = drawData.DisplayPos.Y + drawData.DisplaySize.Y; var mvp = new float[] { 2f / (R - L), 0, 0, 0, 0, 2f / (T - B), 0, 0, 0, 0, 0.5f, 0, (R + L) / (L - R), (T + B) / (B - T), 0.5f, 1f }; var constantBuffer = _deviceContext.MapSubresource(_vertexConstantBuffer, 0, MapMode.WriteDiscard, MapFlags.None).DataPointer; unsafe { fixed(void *mvpPtr = mvp) { System.Buffer.MemoryCopy(mvpPtr, constantBuffer.ToPointer(), 16 * sizeof(float), 16 * sizeof(float)); } } _deviceContext.UnmapSubresource(_vertexConstantBuffer, 0); // Backup DX state that will be modified to restore it afterwards // note that this does nothing if _backupState is false var oldState = BackupState(); // Setup desired DX state SetupRenderState(drawData); // Render command lists // (Because we merged all buffers into a single one, we maintain our own offset into them) vertexOffset = 0; indexOffset = 0; var clipOff = drawData.DisplayPos; for (int n = 0; n < drawData.CmdListsCount; n++) { var cmdList = drawData.CmdListsRange[n]; for (int cmd = 0; cmd < cmdList.CmdBuffer.Size; cmd++) { var pcmd = cmdList.CmdBuffer[cmd]; if (pcmd.UserCallback != IntPtr.Zero) { // TODO throw new NotImplementedException(); } else { // Apply scissor/clipping rectangle _deviceContext.Rasterizer.SetScissorRectangle((int)(pcmd.ClipRect.X - clipOff.X), (int)(pcmd.ClipRect.Y - clipOff.Y), (int)(pcmd.ClipRect.Z - clipOff.X), (int)(pcmd.ClipRect.W - clipOff.Y)); // Bind texture, Draw // Not sure why this bind is done in the loops instead of once per frame, but leaving to match the source for now var textureSrv = ShaderResourceView.FromPointer <ShaderResourceView>(pcmd.TextureId); _deviceContext.PixelShader.SetShaderResource(0, textureSrv); _deviceContext.DrawIndexed((int)pcmd.ElemCount, (int)(pcmd.IdxOffset + indexOffset), (int)(pcmd.VtxOffset + vertexOffset)); } } indexOffset += cmdList.IdxBuffer.Size; vertexOffset += cmdList.VtxBuffer.Size; } // Restore modified DX state RestoreState(oldState); }