public unsafe IndexBuffer CreateImmutableIndexBuffer <T>(T[] data, int offset = 0, int length = -1) where T : unmanaged { int realLength = length == -1 ? data.Length - offset : length; int indexSize = sizeof(T); if (indexSize != 2 && indexSize != 4) { throw new ArgumentException("Invalid index size: " + indexSize); } BufferDescription bd = new BufferDescription() { ByteWidth = (uint)(indexSize * realLength), Usage = 0, //default BindFlags = 2, //indexbuffer CPUAccessFlags = 0, //none. or write (65536) MiscFlags = 0, StructureByteStride = (uint)indexSize, }; fixed(T *pData = &data[offset]) { DataBox box = new DataBox { DataPointer = pData, RowPitch = 0, SlicePitch = 0, }; using (var ib = new ComScopeGuard()) { Device.CreateBuffer(_device.DevicePtr, &bd, &box, out ib.Ptr).Check(); return(new IndexBuffer(_device, ib.Move(), indexSize * 8, realLength)); } } }
public unsafe VertexDataProcessorGroup CreateVertexDataProcessors(Type[] types) { if (_disposed) { throw new ObjectDisposedException("Pipeline"); } var desc = Enumerable.Empty <InputElementDescription>(); var processors = new object[types.Length]; var deviceTypeList = new[] { typeof(LightDevice) }; var deviceObject = new object[] { _device }; for (int i = 0; i < types.Length; ++i) { desc = desc.Concat(InputElementDescriptionFactory.Create(types[i], i)); var processorType = typeof(VertexDataProcessor <>).MakeGenericType(types[i]); var ctor = processorType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, deviceTypeList, null); processors[i] = ctor.Invoke(deviceObject); } var list = desc.ToArray(); using (var layout = new ComScopeGuard()) { fixed(InputElementDescription *d = list) { Device.CreateInputLayout(_device.DevicePtr, d, (uint)list.Length, Blob.GetBufferPointer(_signatureBlob), Blob.GetBufferSize(_signatureBlob), out layout.Ptr).Check(); } return(new VertexDataProcessorGroup(_device, types, processors, layout.Move())); } }
public unsafe VertexBuffer CreateImmutableBuffer(T[] data, int offset = 0, int length = -1) { int realLength = length == -1 ? data.Length - offset : length; BufferDescription bd = new BufferDescription() { ByteWidth = (uint)(_Size * realLength), Usage = 0, //default BindFlags = 1, //vertexbuffer CPUAccessFlags = 0, //none. or write (65536) MiscFlags = 0, StructureByteStride = (uint)_Size }; fixed(T *pData = &data[offset]) { DataBox box = new DataBox { DataPointer = pData, RowPitch = 0, SlicePitch = 0, }; using (var vb = new ComScopeGuard()) { Device.CreateBuffer(_device.DevicePtr, &bd, &box, out vb.Ptr).Check(); return(new VertexBuffer(_device, _bufferUpdate, vb.Move(), _inputLayout.AddRef(), _Size, realLength, false)); } } }
private static IEnumerable <DXGIAdapterDescription> GetAdapterDescription(Predicate <DXGIAdapterDescription> predicate, Action <IntPtr> result) { uint code; using (var factory = new ComScopeGuard()) { Native.CreateDXGIFactory(Guids.Factory, out factory.Ptr).Check(); uint i = 0; do { using (var adapter = new ComScopeGuard()) { code = Factory.EnumAdapters(factory.Ptr, i++, out adapter.Ptr); if (code == 0) { if (GetAdapterDesc(adapter.Ptr, out var desc)) { yield return(desc); if (predicate != null && predicate(desc)) { result.Invoke(adapter.Move()); yield break; } } } } } while (code != 0x887A0002u); } }
//Separate to avoid fat method body (workaround for the Mono.Cecil bug) private unsafe void RebuildBackBuffer() { using (ComScopeGuard backBuffer = new ComScopeGuard(), renderView = new ComScopeGuard()) { SwapChain.GetBuffer(_swapchain, 0, Guids.Texture2D, out backBuffer.Ptr).Check(); Device.CreateRenderTargetView(_device, backBuffer.Ptr, null, out renderView.Ptr).Check(); _defaultRenderView = renderView.Move(); } }
public unsafe Texture2D CreateTexture2D(int width, int height, int format, IntPtr data, int stride, bool isDynamic) { using (ComScopeGuard tex = new ComScopeGuard(), view = new ComScopeGuard()) { tex.Ptr = InternalCreateTexture2D(width, height, format, data, stride, isDynamic); Device.CreateShaderResourceView(_device, tex.Ptr, null, out view.Ptr).Check(); return(new Texture2D(this, tex.Move(), view.Move(), width, height)); } }
public unsafe VertexBuffer CreateDynamicBuffer(int nElement) { BufferDescription bd = new BufferDescription() { ByteWidth = (uint)(_Size * nElement), Usage = 2, //dynamic BindFlags = 1, //vertexbuffer CPUAccessFlags = 0x10000, //write MiscFlags = 0, StructureByteStride = (uint)_Size }; using (var vb = new ComScopeGuard()) { Device.CreateBuffer(_device.DevicePtr, &bd, null, out vb.Ptr).Check(); return(new VertexBuffer(_device, _bufferUpdate, vb.Move(), _inputLayout.AddRef(), _Size, nElement, true)); } }
private static IntPtr GetAdapter() { uint adapterId = AdapterDeviceId; IntPtr ret = IntPtr.Zero; foreach (var i in GetAdapterDescription(d => d.DeviceId == adapterId, d => ret = d)) { } if (ret == IntPtr.Zero) { using (var factory = new ComScopeGuard()) { Native.CreateDXGIFactory(Guids.Factory, out factory.Ptr).Check(); Factory.EnumAdapters(factory.Ptr, 0, out ret).Check(); } } return(ret); }
private unsafe Pipeline CompilePipeline(ShaderSource srcVS, ShaderSource srcGS, ShaderSource srcPS, InputTopology topology) { using (ComScopeGuard vertexShader = new ComScopeGuard(), pixelShader = new ComScopeGuard(), geometryShader = new ComScopeGuard(), signatureBlob = new ComScopeGuard()) { if (srcVS != null) fixed(byte *codePtr = srcVS.Data) { using (var blob = new ComScopeGuard()) { blob.Ptr = Compile(codePtr, srcVS.Data.Length, CompilerStringConstants.VS, CompilerStringConstants.vs_4_0); Device.CreateVertexShader(_device, Blob.GetBufferPointer(blob.Ptr), Blob.GetBufferSize(blob.Ptr), IntPtr.Zero, out vertexShader.Ptr); Native.D3DGetInputSignatureBlob( Blob.GetBufferPointer(blob.Ptr), Blob.GetBufferSize(blob.Ptr), out signatureBlob.Ptr); } } if (srcGS != null) fixed(byte *codePtr = srcGS.Data) { using (var blob = new ComScopeGuard()) { blob.Ptr = Compile(codePtr, srcGS.Data.Length, CompilerStringConstants.GS, CompilerStringConstants.gs_4_0); Device.CreateGeometryShader(_device, Blob.GetBufferPointer(blob.Ptr), Blob.GetBufferSize(blob.Ptr), IntPtr.Zero, out geometryShader.Ptr); } } fixed(byte *codePtr = srcPS.Data) { using (var blob = new ComScopeGuard()) { blob.Ptr = Compile(codePtr, srcPS.Data.Length, CompilerStringConstants.PS, CompilerStringConstants.ps_4_0); Device.CreatePixelShader(_device, Blob.GetBufferPointer(blob.Ptr), Blob.GetBufferSize(blob.Ptr), IntPtr.Zero, out pixelShader.Ptr); } } return(new Pipeline(this, vertexShader.Move(), geometryShader.Move(), pixelShader.Move(), signatureBlob.Move(), topology)); } //using }
private unsafe void RebuildViewTextureInternal(ref Texture2DDescription desc) { using (ComScopeGuard tex = new ComScopeGuard(), targetView = new ComScopeGuard(), resView = new ComScopeGuard()) { int *renderTargetDesc = stackalloc int[5] { _formatTarget, 4, //D3D11_RTV_DIMENSION_TEXTURE2D 0, //MipSlice = 0 0, //Not used in tex2d 0, //Not used in tex2d }; Natives.Device.CreateTexture2D(_device.DevicePtr, ref desc, IntPtr.Zero, out tex.Ptr).Check(); Natives.Device.CreateRenderTargetView(_device.DevicePtr, tex.Ptr, renderTargetDesc, out targetView.Ptr).Check(); _TexturePtr = tex.Move(); _viewPtrTarget = targetView.Move(); } RebuildResourceView(); }
//Note: The following 2 methods are separated from RebuildView to avoid fat method to be modified by Mono.Cecil, //which when doing so will corrupt the binary for unknown reason. private unsafe void RebuildViewStencilInternal(ref Texture2DDescription desc) { using (var depthTex = new ComScopeGuard()) { int *depthStencilDesc = stackalloc int[6] { _formatTarget, 3, //D3D11_DSV_DIMENSION_TEXTURE2D 0, //Flags = 0 0, //MipSlice = 0 0, 0, }; Natives.Device.CreateTexture2D(_device.DevicePtr, ref desc, IntPtr.Zero, out depthTex.Ptr).Check(); Natives.Device.CreateDepthStencilView(_device.DevicePtr, depthTex.Ptr, depthStencilDesc, out _viewPtrTarget).Check(); _TexturePtr = depthTex.Move(); } RebuildResourceView(); }
public unsafe ShaderResourceBuffer <T> CreateShaderResourceBuffer <T>(T[] data, bool isStructured) where T : unmanaged { var elementSize = Marshal.SizeOf <T>(); BufferDescription bd = new BufferDescription() { ByteWidth = (uint)(elementSize * data.Length), Usage = 1, //immutable BindFlags = 8, //shader resource CPUAccessFlags = 0, //none MiscFlags = isStructured ? 64u : 0u, //D3D11_RESOURCE_MISC_BUFFER_STRUCTURED StructureByteStride = (uint)elementSize, }; using (var buffer = new ComScopeGuard()) { fixed(T *pData = &data[0]) { DataBox box = new DataBox { DataPointer = pData, RowPitch = 0, SlicePitch = 0, }; Device.CreateBuffer(_device.DevicePtr, &bd, &box, out buffer.Ptr).Check(); } using (var view = new ComScopeGuard()) { int *viewDesc = stackalloc int[5] { isStructured ? 0 : InputElementDescriptionFactory.GetFormatFromType(typeof(T)), isStructured ? 11 : 1, //D3D_SRV_DIMENSION_BUFFEREX or D3D_SRV_DIMENSION_BUFFER 0, //FirstElement = 0 data.Length, //NumElements 0, //Not used }; Device.CreateShaderResourceView(_device.DevicePtr, buffer.Ptr, viewDesc, out view.Ptr).Check(); return(new ShaderResourceBuffer <T>(_device, buffer.Move(), view.Move())); } } }
public unsafe VertexDataProcessor <T> CreateVertexDataProcessor <T>() where T : unmanaged { if (_disposed) { throw new ObjectDisposedException("Pipeline"); } var layoutDecl = VertexDataProcessor <T> .CreateLayoutFromType(0); using (var layout = new ComScopeGuard()) { fixed(InputElementDescription *d = layoutDecl) { Device.CreateInputLayout(_device.DevicePtr, d, (uint)layoutDecl.Length, Blob.GetBufferPointer(_signatureBlob), Blob.GetBufferSize(_signatureBlob), out layout.Ptr).Check(); } return(new VertexDataProcessor <T>(_device, layout.Move())); } }
private unsafe IntPtr Compile(byte *codePtr, int length, IntPtr p1, IntPtr p2) { using (ComScopeGuard blob = new ComScopeGuard(), msg = new ComScopeGuard()) { var e = Native.D3DCompile(codePtr, length, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, p1, p2, 0, 0, out blob.Ptr, out msg.Ptr); if (blob.Ptr == IntPtr.Zero) { if (msg.Ptr != IntPtr.Zero) { var msgStr = Marshal.PtrToStringAnsi(Blob.GetBufferPointer(msg.Ptr)); throw new NativeException(e, msgStr); } else { throw new NativeException(e); } } return(blob.Move()); } }
public unsafe IndexBuffer CreateDynamicIndexBuffer(int bitWidth, int size) { if (bitWidth != 16 && bitWidth != 32) { throw new ArgumentOutOfRangeException(nameof(bitWidth)); } BufferDescription bd = new BufferDescription() { ByteWidth = (uint)(bitWidth / 8 * size), Usage = 2, //dynamic BindFlags = 2, //indexbuffer CPUAccessFlags = 0x10000, //write MiscFlags = 0, StructureByteStride = (uint)bitWidth / 8, }; using (var ib = new ComScopeGuard()) { Device.CreateBuffer(_device.DevicePtr, &bd, null, out ib.Ptr).Check(); return(new IndexBuffer(_device, ib.Move(), bitWidth, size)); } }
public unsafe ConstantBuffer <T> CreateConstantBuffer <T>() where T : unmanaged { if (_disposed) { throw new ObjectDisposedException("Pipeline"); } BufferDescription bd = new BufferDescription() { ByteWidth = (((uint)Marshal.SizeOf <T>() + 15) & ~15u), //multiples of 16 Usage = 2, //dynamic BindFlags = 4, //constantbuffer CPUAccessFlags = 0x10000, //write MiscFlags = 0, StructureByteStride = 0, // (uint)(Marshal.SizeOf<T>()), }; using (var cb = new ComScopeGuard()) { Device.CreateBuffer(_device.DevicePtr, &bd, null, out cb.Ptr).Check(); return(new ConstantBuffer <T>(_device, cb.Move())); } }
public unsafe static LightDevice Create(Control ctrl, int initWidth = -1, int initHeight = -1) { var ret = new LightDevice(); //initialize size { var width = initWidth == -1 ? ctrl.ClientSize.Width : initWidth; var height = initHeight == -1 ? ctrl.ClientSize.Height : initHeight; ret._ctrl = ctrl; ret._form = ctrl.FindForm(); ret._width = width; ret._height = height; ret._dpi = GetDpiForWindow(ret._form.Handle); } try { using (var adapter = new ComScopeGuard()) { //Find the adapter adapter.Ptr = GetAdapter(); //create core objects IntPtr swapChain, device, immediateContext; { var d = new SwapChainDescription(ctrl.Handle, ret._width, ret._height); Native.D3D11CreateDeviceAndSwapChain( adapter.Ptr, adapter.Ptr == IntPtr.Zero ? 1u : 0u, IntPtr.Zero, 0, IntPtr.Zero, 0, 7, ref d, out swapChain, out device, out var featureLevel, out immediateContext).Check(); ret._device = device; ret._swapchain = swapChain; ret._context = immediateContext; } //get default render target IntPtr renderView; { using (var backBuffer = new ComScopeGuard()) { SwapChain.GetBuffer(swapChain, 0, Guids.Texture2D, out backBuffer.Ptr).Check(); Device.CreateRenderTargetView(device, backBuffer.Ptr, null, out renderView).Check(); } ret._defaultRenderView = renderView; } //get DXGI.Output { var i = Adapter.EnumOutputs(adapter.Ptr, 0, out var output); //Sometimes this can fail, but it should not affect our other functions. //TODO Actually we should think of supporting multiple outputs. if (i != 0x887A0002) { i.Check(); } ret._output = output; } ret._defaultRenderTarget = RenderTargetObject.CreateSwapchainTarget(ret); ret.AddEventHandlers(); } } catch (NativeException e) { ret.Dispose(true); throw e; } return(ret); }