예제 #1
0
파일: Pipeline.cs 프로젝트: acaly/LightDx
        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));
                }
            }
        }
예제 #2
0
파일: Pipeline.cs 프로젝트: acaly/LightDx
        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()));
            }
        }
예제 #3
0
        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));
                }
            }
        }
예제 #4
0
        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);
            }
        }
예제 #5
0
 //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();
     }
 }
예제 #6
0
 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));
     }
 }
예제 #7
0
        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));
            }
        }
예제 #8
0
        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);
        }
예제 #9
0
        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
        }
예제 #10
0
 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();
 }
예제 #11
0
        //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();
        }
예제 #12
0
파일: Pipeline.cs 프로젝트: acaly/LightDx
        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()));
                }
            }
        }
예제 #13
0
파일: Pipeline.cs 프로젝트: acaly/LightDx
        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()));
            }
        }
예제 #14
0
 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());
     }
 }
예제 #15
0
파일: Pipeline.cs 프로젝트: acaly/LightDx
        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));
            }
        }
예제 #16
0
파일: Pipeline.cs 프로젝트: acaly/LightDx
        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()));
            }
        }
예제 #17
0
        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);
        }