Exemplo n.º 1
0
        static void Main()
        {
            RenderForm window = new RenderForm("Some title");

            SwapChainDescription swapChainDesc = new SwapChainDescription()
            {
                BufferCount = 1,
                ModeDescription = new ModeDescription(window.ClientSize.Width, window.ClientSize.Height, new Rational(60, 1), Format.R8G8B8A8_UNorm),
                IsWindowed = true,
                OutputHandle = window.Handle,
                SampleDescription = new SampleDescription(1, 0),
                SwapEffect = SwapEffect.Discard,
                Usage = Usage.RenderTargetOutput
            };

            //debug
            Configuration.EnableObjectTracking = true;

            D3D11Device device;
            SwapChain swapChain;
            D3D11Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.None, swapChainDesc, out device, out swapChain);
            DeviceContext context = device.ImmediateContext;
            Factory factory = swapChain.GetParent<Factory>();
            factory.MakeWindowAssociation(window.Handle, WindowAssociationFlags.IgnoreAll);

            Stopwatch clock = new Stopwatch();
            clock.Start();

            bool resized = true;
            window.UserResized += (sender, args) => resized = true;

            window.KeyUp += (sender, args) =>
                {
                    if (args.KeyCode == Keys.F5)
                        swapChain.SetFullscreenState(true, null);
                    else if (args.KeyCode == Keys.F4)
                        swapChain.SetFullscreenState(false, null);
                    else if (args.KeyCode == Keys.Enter)
                        window.Close();
                };

            RenderLoop.Run(window, () =>
                {
                    swapChain.Present(0, PresentFlags.None);
                });

            context.Flush();
            device.Dispose();
            context.Dispose();
            swapChain.Dispose();
            factory.Dispose();
        }
Exemplo n.º 2
0
  //      [STAThread]
        private static void Main()
        {
            var form = new RenderForm("SharpDX - MiniCube Direct3D11 Sample");

            // SwapChain description
            var desc = new SwapChainDescription()
            {
                BufferCount = 1,
                ModeDescription =
                    new ModeDescription(form.ClientSize.Width, form.ClientSize.Height,
                                        new Rational(60, 1), Format.R8G8B8A8_UNorm),
                IsWindowed = true,
                OutputHandle = form.Handle,
                SampleDescription = new SampleDescription(1, 0),
                SwapEffect = SwapEffect.Discard,
                Usage = Usage.RenderTargetOutput
            };

            // Used for debugging dispose object references
            // Configuration.EnableObjectTracking = true;

            // Disable throws on shader compilation errors
            //Configuration.ThrowOnShaderCompileError = false;

            // Create Device and SwapChain
            Device device;
            SwapChain swapChain;
            Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.None, desc, out device, out swapChain);
            var context = device.ImmediateContext;

            // Ignore all windows events
            var factory = swapChain.GetParent<Factory>();
            factory.MakeWindowAssociation(form.Handle, WindowAssociationFlags.IgnoreAll);

            // Compile Vertex and Pixel shaders
            var vertexShaderByteCode = ShaderBytecode.CompileFromFile("MiniCube.fx", "VS", "vs_4_0");
            var vertexShader = new VertexShader(device, vertexShaderByteCode);

            var pixelShaderByteCode = ShaderBytecode.CompileFromFile("MiniCube.fx", "PS", "ps_4_0");
            var pixelShader = new PixelShader(device, pixelShaderByteCode);

            var signature = ShaderSignature.GetInputSignature(vertexShaderByteCode);
            // Layout from VertexShader input signature
            var layout = new InputLayout(device, signature, new[]
                    {
                        new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
                        new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 16, 0)
                    });

            // Instantiate Vertex buiffer from vertex data
            var vertices = Buffer.Create(device, BindFlags.VertexBuffer, new[]
                                  {
                                      new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), // Front
                                      new Vector4(-1.0f,  1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
                                      new Vector4( 1.0f,  1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
                                      new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
                                      new Vector4( 1.0f,  1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
                                      new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),

                                      new Vector4(-1.0f, -1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), // BACK
                                      new Vector4( 1.0f,  1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
                                      new Vector4(-1.0f,  1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
                                      new Vector4(-1.0f, -1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
                                      new Vector4( 1.0f, -1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
                                      new Vector4( 1.0f,  1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),

                                      new Vector4(-1.0f, 1.0f, -1.0f,  1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), // Top
                                      new Vector4(-1.0f, 1.0f,  1.0f,  1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
                                      new Vector4( 1.0f, 1.0f,  1.0f,  1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
                                      new Vector4(-1.0f, 1.0f, -1.0f,  1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
                                      new Vector4( 1.0f, 1.0f,  1.0f,  1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
                                      new Vector4( 1.0f, 1.0f, -1.0f,  1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),

                                      new Vector4(-1.0f,-1.0f, -1.0f,  1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f), // Bottom
                                      new Vector4( 1.0f,-1.0f,  1.0f,  1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
                                      new Vector4(-1.0f,-1.0f,  1.0f,  1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
                                      new Vector4(-1.0f,-1.0f, -1.0f,  1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
                                      new Vector4( 1.0f,-1.0f, -1.0f,  1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
                                      new Vector4( 1.0f,-1.0f,  1.0f,  1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),

                                      new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f), // Left
                                      new Vector4(-1.0f, -1.0f,  1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
                                      new Vector4(-1.0f,  1.0f,  1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
                                      new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
                                      new Vector4(-1.0f,  1.0f,  1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
                                      new Vector4(-1.0f,  1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),

                                      new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f), // Right
                                      new Vector4( 1.0f,  1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
                                      new Vector4( 1.0f, -1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
                                      new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
                                      new Vector4( 1.0f,  1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
                                      new Vector4( 1.0f,  1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
                            });

            // Create Constant Buffer
            var contantBuffer = new Buffer(device, Utilities.SizeOf<Matrix>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);



            // Prepare All the stages
            context.InputAssembler.InputLayout = layout;
            context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
            context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertices, Utilities.SizeOf<Vector4>() * 2, 0));
            context.VertexShader.SetConstantBuffer(0, contantBuffer);
            context.VertexShader.Set(vertexShader);
            context.PixelShader.Set(pixelShader);

            // Prepare matrices
            var view = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 0), Vector3.UnitY);
            Matrix proj = Matrix.Identity;

            // Use clock
            var clock = new Stopwatch();
            clock.Start();

            // Declare texture for rendering
            bool userResized = true;
            Texture2D backBuffer = null;
            RenderTargetView renderView = null;
            Texture2D depthBuffer = null;
            DepthStencilView depthView = null;

            // Setup handler on resize form
            form.UserResized += (sender, args) => userResized = true;

            // Setup full screen mode change F5 (Full) F4 (Window)
            form.KeyUp += (sender, args) =>
                {
                    if (args.KeyCode == Keys.F5)
                        swapChain.SetFullscreenState(true, null);
                    else if (args.KeyCode == Keys.F4)
                        swapChain.SetFullscreenState(false, null);
                    else if (args.KeyCode == Keys.Escape)
                        form.Close();
                };

            // Main loop
            RenderLoop.Run(form, () =>
            {
                // If Form resized
                if (userResized)
                {
                    // Dispose all previous allocated resources
                    ComObject.Dispose(ref backBuffer);
                    ComObject.Dispose(ref renderView);
                    ComObject.Dispose(ref depthBuffer);
                    ComObject.Dispose(ref depthView);

                    // Resize the backbuffer
                    swapChain.ResizeBuffers(desc.BufferCount, form.ClientSize.Width, form.ClientSize.Height, Format.Unknown, SwapChainFlags.None);

                    // Get the backbuffer from the swapchain
                    backBuffer = Texture2D.FromSwapChain<Texture2D>(swapChain, 0);

                    // Renderview on the backbuffer
                    renderView = new RenderTargetView(device, backBuffer);

                    // Create the depth buffer
                    depthBuffer = new Texture2D(device, new Texture2DDescription()
                    {
                        Format = Format.D32_Float_S8X24_UInt,
                        ArraySize = 1,
                        MipLevels = 1,
                        Width = form.ClientSize.Width,
                        Height = form.ClientSize.Height,
                        SampleDescription = new SampleDescription(1, 0),
                        Usage = ResourceUsage.Default,
                        BindFlags = BindFlags.DepthStencil,
                        CpuAccessFlags = CpuAccessFlags.None,
                        OptionFlags = ResourceOptionFlags.None
                    });

                    // Create the depth buffer view
                    depthView = new DepthStencilView(device, depthBuffer);

                    // Setup targets and viewport for rendering
                    context.Rasterizer.SetViewports(new Viewport(0, 0, form.ClientSize.Width, form.ClientSize.Height, 0.0f, 1.0f));
                    context.OutputMerger.SetTargets(depthView, renderView);

                    // Setup new projection matrix with correct aspect ratio
                    proj = Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, form.ClientSize.Width / (float)form.ClientSize.Height, 0.1f, 100.0f);

                    // We are done resizing
                    userResized = false;
                }

                var time = clock.ElapsedMilliseconds / 1000.0f;

                var viewProj = Matrix.Multiply(view, proj);

                // Clear views
                context.ClearDepthStencilView(depthView, DepthStencilClearFlags.Depth, 1.0f, 0);
                context.ClearRenderTargetView(renderView, Color.Black);

                // Update WorldViewProj Matrix
                var worldViewProj = Matrix.RotationX(time) * Matrix.RotationY(time * 2) * Matrix.RotationZ(time * .7f) * viewProj;
                worldViewProj.Transpose();
                context.UpdateSubresource(ref worldViewProj, contantBuffer);

                // Draw the cube
                context.Draw(36, 0);

                // Present!
                swapChain.Present(0, PresentFlags.None);
            });

            // Release all resources
            signature.Dispose();
            vertexShaderByteCode.Dispose();
            vertexShader.Dispose();
            pixelShaderByteCode.Dispose();
            pixelShader.Dispose();
            vertices.Dispose();
            layout.Dispose();
            contantBuffer.Dispose();
            depthBuffer.Dispose();
            depthView.Dispose();
            renderView.Dispose();
            backBuffer.Dispose();
            context.ClearState();
            context.Flush();
            device.Dispose();
            context.Dispose();
            swapChain.Dispose();
            factory.Dispose();
        }
Exemplo n.º 3
0
        public void Run()
        {

            // Initial state
            var currentState = new State
            {
                // Set the number of cubes to display (horizontally and vertically) 
                CountCubes = 64,
                // Number of threads to run concurrently 
                ThreadCount = 4,
                // Use deferred by default
                Type = TestType.Deferred,
                // BurnCpu by default
                SimulateCpuUsage = true,
                // Default is using Map/Unmap
                UseMap = true,
            };
            var nextState = currentState;

            // --------------------------------------------------------------------------------------
            // Init Direct3D11
            // --------------------------------------------------------------------------------------

            // Create the Rendering form 
            var form = new RenderForm("SharpDX - MiniCube Direct3D11");
            form.ClientSize = new Size(1024, 1024);

            // SwapChain description 
            var desc = new SwapChainDescription()
            {
                BufferCount = 2,
                ModeDescription =
                    new ModeDescription(form.ClientSize.Width, form.ClientSize.Height,
                                        new Rational(60, 1), Format.R8G8B8A8_UNorm),
                IsWindowed = true,
                OutputHandle = form.Handle,
                SampleDescription = new SampleDescription(1, 0),
                SwapEffect = SwapEffect.Discard,
                Usage = Usage.RenderTargetOutput
            };

            // Create Device and SwapChain 
            Device device;
            SwapChain swapChain;
            Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.None, desc, out device, out swapChain);
            var immediateContext = device.ImmediateContext;
            device = ToDispose(device);

            // PreCreate deferred contexts 
            var deferredContexts = new DeviceContext[MaxNumberOfThreads];
            for (int i = 0; i < deferredContexts.Length; i++)
                deferredContexts[i] = ToDispose(new DeviceContext(device));

            // Allocate rendering context array 
            var contextPerThread = new DeviceContext[MaxNumberOfThreads];
            contextPerThread[0] = immediateContext;
            var commandLists = new CommandList[MaxNumberOfThreads];
            CommandList[] frozenCommandLists = null;

            // Check if driver is supporting natively CommandList
            bool supportConcurentResources;
            bool supportCommandList;
            device.CheckThreadingSupport(out supportConcurentResources, out supportCommandList);

            // Ignore all windows events 
            var factory = ToDispose(swapChain.GetParent<Factory>());
            factory.MakeWindowAssociation(form.Handle, WindowAssociationFlags.IgnoreAll);

            // New RenderTargetView from the backbuffer 
            var backBuffer = ToDispose(Texture2D.FromSwapChain<Texture2D>(swapChain, 0));
            var renderView = ToDispose(new RenderTargetView(device, backBuffer));

            // Compile Vertex and Pixel shaders 
            var bytecode = ShaderBytecode.Compile(Resources.MultiCube, "VS", "vs_4_0");
            var vertexShader = ToDispose(new VertexShader(device, bytecode));

            // Layout from VertexShader input signature 
            var layout = ToDispose(new InputLayout(device, ToDispose(ShaderSignature.GetInputSignature(bytecode)), new[] 
                    { 
                        new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0), 
                        new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 16, 0) 
                    }));
            bytecode.Dispose();

            bytecode = ToDispose(ShaderBytecode.Compile(Resources.MultiCube, "PS", "ps_4_0"));
            var pixelShader = ToDispose(new PixelShader(device, bytecode));
            bytecode.Dispose();

            // Instantiate Vertex buiffer from vertex data 
            var vertices = ToDispose(Buffer.Create(device, BindFlags.VertexBuffer, new[] 
                                  { 
                                      new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), // Front 
                                      new Vector4(-1.0f,  1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), 
                                      new Vector4( 1.0f,  1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), 
                                      new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), 
                                      new Vector4( 1.0f,  1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), 
                                      new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), 
 
                                      new Vector4(-1.0f, -1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), // BACK 
                                      new Vector4( 1.0f,  1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), 
                                      new Vector4(-1.0f,  1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), 
                                      new Vector4(-1.0f, -1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), 
                                      new Vector4( 1.0f, -1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), 
                                      new Vector4( 1.0f,  1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), 
 
                                      new Vector4(-1.0f, 1.0f, -1.0f,  1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), // Top 
                                      new Vector4(-1.0f, 1.0f,  1.0f,  1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), 
                                      new Vector4( 1.0f, 1.0f,  1.0f,  1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), 
                                      new Vector4(-1.0f, 1.0f, -1.0f,  1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), 
                                      new Vector4( 1.0f, 1.0f,  1.0f,  1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), 
                                      new Vector4( 1.0f, 1.0f, -1.0f,  1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), 
 
                                      new Vector4(-1.0f,-1.0f, -1.0f,  1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f), // Bottom 
                                      new Vector4( 1.0f,-1.0f,  1.0f,  1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f), 
                                      new Vector4(-1.0f,-1.0f,  1.0f,  1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f), 
                                      new Vector4(-1.0f,-1.0f, -1.0f,  1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f), 
                                      new Vector4( 1.0f,-1.0f, -1.0f,  1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f), 
                                      new Vector4( 1.0f,-1.0f,  1.0f,  1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f), 
 
                                      new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f), // Left 
                                      new Vector4(-1.0f, -1.0f,  1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f), 
                                      new Vector4(-1.0f,  1.0f,  1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f), 
                                      new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f), 
                                      new Vector4(-1.0f,  1.0f,  1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f), 
                                      new Vector4(-1.0f,  1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f), 
 
                                      new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f), // Right 
                                      new Vector4( 1.0f,  1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f), 
                                      new Vector4( 1.0f, -1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f), 
                                      new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f), 
                                      new Vector4( 1.0f,  1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f), 
                                      new Vector4( 1.0f,  1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f), 
                            }));

            // Create Constant Buffer 
            var staticContantBuffer = ToDispose(new Buffer(device, Utilities.SizeOf<Matrix>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0));
            var dynamicConstantBuffer = ToDispose(new Buffer(device, Utilities.SizeOf<Matrix>(), ResourceUsage.Dynamic, BindFlags.ConstantBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None, 0));

            // Create Depth Buffer & View 
            var depthBuffer = ToDispose(new Texture2D(device, new Texture2DDescription()
            {
                Format = Format.D32_Float_S8X24_UInt,
                ArraySize = 1,
                MipLevels = 1,
                Width = form.ClientSize.Width,
                Height = form.ClientSize.Height,
                SampleDescription = new SampleDescription(1, 0),
                Usage = ResourceUsage.Default,
                BindFlags = BindFlags.DepthStencil,
                CpuAccessFlags = CpuAccessFlags.None,
                OptionFlags = ResourceOptionFlags.None
            }));

            var depthView = ToDispose(new DepthStencilView(device, depthBuffer));

            // --------------------------------------------------------------------------------------
            // Prepare matrices & clocks
            // --------------------------------------------------------------------------------------

            const float viewZ = 5.0f;

            // Prepare matrices 
            var view = Matrix.LookAtLH(new Vector3(0, 0, -viewZ), new Vector3(0, 0, 0), Vector3.UnitY);
            var proj = Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, form.ClientSize.Width / (float)form.ClientSize.Height, 0.1f, 100.0f);
            var viewProj = Matrix.Multiply(view, proj);

            // Use clock 
            var clock = new Stopwatch();
            clock.Start();

            var fpsTimer = new Stopwatch();
            fpsTimer.Start();
            int fpsCounter = 0;

            // --------------------------------------------------------------------------------------
            // Register KeyDown event handler on the form
            // --------------------------------------------------------------------------------------
            bool switchToNextState = false;

            // Install keys handlers 
            form.KeyDown += (target, arg) =>
            {
                if (arg.KeyCode == Keys.Left && nextState.CountCubes > 1)
                    nextState.CountCubes--;
                if (arg.KeyCode == Keys.Right && nextState.CountCubes < MaxNumberOfCubes)
                    nextState.CountCubes++;

                if (arg.KeyCode == Keys.F1)
                    nextState.Type= (TestType)((((int)nextState.Type) + 1) % 3);
                if (arg.KeyCode == Keys.F2)
                    nextState.UseMap = !nextState.UseMap;
                if (arg.KeyCode == Keys.F3)
                    nextState.SimulateCpuUsage = !nextState.SimulateCpuUsage;

                if (nextState.Type == TestType.Deferred)
                {
                    if (arg.KeyCode == Keys.Down && nextState.ThreadCount > 1)
                        nextState.ThreadCount--;
                    if (arg.KeyCode == Keys.Up && nextState.ThreadCount < MaxNumberOfThreads)
                        nextState.ThreadCount++;
                }
                if (arg.KeyCode == Keys.Escape)
                    nextState.Exit = true;
                switchToNextState = true;
            };

            // --------------------------------------------------------------------------------------
            // Function used to setup the pipeline
            // --------------------------------------------------------------------------------------
            Action SetupPipeline = () =>
            {
                int threadCount = 1;
                if (currentState.Type != TestType.Immediate)
                {
                    threadCount = currentState.Type == TestType.Deferred ? currentState.ThreadCount : 1;
                    Array.Copy(deferredContexts, contextPerThread, contextPerThread.Length);
                }
                else
                {
                    contextPerThread[0] = immediateContext;
                }
                for (int i = 0; i < threadCount; i++)
                {
                    var renderingContext = contextPerThread[i];
                    // Prepare All the stages 
                    renderingContext.InputAssembler.InputLayout = layout;
                    renderingContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
                    renderingContext.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertices, Utilities.SizeOf<Vector4>() * 2, 0));
                    renderingContext.VertexShader.SetConstantBuffer(0, currentState.UseMap ? dynamicConstantBuffer : staticContantBuffer);
                    renderingContext.VertexShader.Set(vertexShader);
                    renderingContext.Rasterizer.SetViewport(0, 0, form.ClientSize.Width, form.ClientSize.Height);
                    renderingContext.PixelShader.Set(pixelShader);
                    renderingContext.OutputMerger.SetTargets(depthView, renderView);
                }
            };

            // --------------------------------------------------------------------------------------
            // Function used to render a row of cubes
            // --------------------------------------------------------------------------------------
            Action<int, int, int> RenderRow = (int contextIndex, int fromY, int toY) =>
            {
                var renderingContext = contextPerThread[contextIndex];
                var time = clock.ElapsedMilliseconds / 1000.0f;

                if (contextIndex == 0)
                {
                    contextPerThread[0].ClearDepthStencilView(depthView, DepthStencilClearFlags.Depth, 1.0f, 0);
                    contextPerThread[0].ClearRenderTargetView(renderView, Color.Black);
                }

                int count = currentState.CountCubes;
                float divCubes = (float)count / (viewZ - 1);

                var rotateMatrix = Matrix.Scaling(1.0f / count) * Matrix.RotationX(time) * Matrix.RotationY(time * 2) * Matrix.RotationZ(time * .7f);

                for (int y = fromY; y < toY; y++)
                {
                    for (int x = 0; x < count; x++)
                    {
                        rotateMatrix.M41 = (x + .5f - count * .5f) / divCubes;
                        rotateMatrix.M42 = (y + .5f - count * .5f) / divCubes;

                        // Update WorldViewProj Matrix 
                        Matrix worldViewProj;
                        Matrix.Multiply(ref rotateMatrix, ref viewProj, out worldViewProj);
                        worldViewProj.Transpose();
                        // Simulate CPU usage in order to see benefits of worlViewProj

                        if (currentState.SimulateCpuUsage)
                        {
                            for (int i = 0; i < BurnCpuFactor; i++)
                            {
                                Matrix.Multiply(ref rotateMatrix, ref viewProj, out worldViewProj);
                                worldViewProj.Transpose();
                            }
                        }

                        if (currentState.UseMap)
                        {
                            var dataBox = renderingContext.MapSubresource(dynamicConstantBuffer, 0, MapMode.WriteDiscard, MapFlags.None);
                            Utilities.Write(dataBox.DataPointer, ref worldViewProj);
                            renderingContext.UnmapSubresource(dynamicConstantBuffer, 0);
                        }
                        else
                        {
                            renderingContext.UpdateSubresource(ref worldViewProj, staticContantBuffer);
                        }

                        // Draw the cube 
                        renderingContext.Draw(36, 0);
                    }
                }

                if (currentState.Type != TestType.Immediate)
                    commandLists[contextIndex] = renderingContext.FinishCommandList(false);
            };


            Action<int> RenderDeferred = (int threadCount) =>
                {
                    int deltaCube = currentState.CountCubes / threadCount;
                    if (deltaCube == 0) deltaCube = 1;
                    int nextStartingRow = 0;
                    var tasks = new Task[threadCount];
                    for (int i = 0; i < threadCount; i++)
                    {
                        var threadIndex = i;
                        int fromRow = nextStartingRow;
                        int toRow = (i + 1) == threadCount ? currentState.CountCubes : fromRow + deltaCube;
                        if (toRow > currentState.CountCubes)
                            toRow = currentState.CountCubes;
                        nextStartingRow = toRow;

                        tasks[i] = new Task(() => RenderRow(threadIndex, fromRow, toRow) );
                        tasks[i].Start();
                    }
                    Task.WaitAll(tasks);
                };


            // --------------------------------------------------------------------------------------
            // Main Loop
            // --------------------------------------------------------------------------------------
            RenderLoop.Run(form, () =>
            {
                if (currentState.Exit)
                    form.Close();

                fpsCounter++;
                if (fpsTimer.ElapsedMilliseconds > 1000)
                {
                    var typeStr = currentState.Type.ToString();
                    if (currentState.Type != TestType.Immediate && !supportCommandList) typeStr += "*";

                    form.Text = string.Format("SharpDX - MultiCube D3D11 - (F1) {0} - (F2) {1} - (F3) {2} - Threads ↑↓{3} - Count ←{4}→ - FPS: {5:F2} ({6:F2}ms)", typeStr, currentState.UseMap ? "Map/UnMap" : "UpdateSubresource", currentState.SimulateCpuUsage ? "BurnCPU On" : "BurnCpu Off", currentState.Type == TestType.Deferred ? currentState.ThreadCount : 1, currentState.CountCubes * currentState.CountCubes, 1000.0 * fpsCounter / fpsTimer.ElapsedMilliseconds, (float)fpsTimer.ElapsedMilliseconds / fpsCounter);
                    fpsTimer.Reset();
                    fpsTimer.Stop();
                    fpsTimer.Start();
                    fpsCounter = 0;
                }

                // Setup the pipeline before any rendering
                SetupPipeline();

                // Execute on the rendering thread when ThreadCount == 1 or No deferred rendering is selected
                if (currentState.Type == TestType.Immediate || ( currentState.Type == TestType.Deferred && currentState.ThreadCount == 1))
                {
                    RenderRow(0, 0, currentState.CountCubes);
                }

                // In case of deferred context, use of FinishCommandList / ExecuteCommandList
                if (currentState.Type != TestType.Immediate)
                {
                    if (currentState.Type == TestType.FrozenDeferred)
                    {
                        if (commandLists[0] == null)
                            RenderDeferred(1);
                    } 
                    else if (currentState.ThreadCount > 1)
                    {
                        RenderDeferred(currentState.ThreadCount);
                    }

                    for (int i = 0; i < currentState.ThreadCount; i++)
                    {
                        var commandList = commandLists[i];
                        // Execute the deferred command list on the immediate context
                        immediateContext.ExecuteCommandList(commandList, false);

                        // For classic deferred we release the command list. Not for frozen
                        if (currentState.Type == TestType.Deferred)
                        {
                            // Release the command list
                            commandList.Dispose();
                            commandLists[i] = null;
                        }
                    }
                }

                if (switchToNextState)
                {
                    currentState = nextState;
                    switchToNextState = false;
                }

                // Present! 
                swapChain.Present(0, PresentFlags.None);
            });

            // Dispose all resource created
            Dispose();
        }
Exemplo n.º 4
0
        public void Run()
        {
            var form = new RenderForm("2d and 3d combined...it's like magic");
            form.KeyDown += (sender, args) => { if (args.KeyCode == Keys.Escape) form.Close(); };

            // DirectX DXGI 1.1 factory
            var factory1 = new Factory1();

            // The 1st graphics adapter
            var adapter1 = factory1.GetAdapter1(0);

            // ---------------------------------------------------------------------------------------------
            // Setup direct 3d version 11. It's context will be used to combine the two elements
            // ---------------------------------------------------------------------------------------------

            var description = new SwapChainDescription
                {
                    BufferCount = 1,
                    ModeDescription = new ModeDescription(0, 0, new Rational(60, 1), Format.R8G8B8A8_UNorm),
                    IsWindowed = true,
                    OutputHandle = form.Handle,
                    SampleDescription = new SampleDescription(1, 0),
                    SwapEffect = SwapEffect.Discard,
                    Usage = Usage.RenderTargetOutput,
                    Flags = SwapChainFlags.AllowModeSwitch
                };

            Device11 device11;
            SwapChain swapChain;

            Device11.CreateWithSwapChain(adapter1, DeviceCreationFlags.None, description, out device11, out swapChain);

            // create a view of our render target, which is the backbuffer of the swap chain we just created
            RenderTargetView renderTargetView;
            using (var resource = Resource.FromSwapChain<Texture2D>(swapChain, 0))
                renderTargetView = new RenderTargetView(device11, resource);

            // setting a viewport is required if you want to actually see anything
            var context = device11.ImmediateContext;

            var viewport = new Viewport(0.0f, 0.0f, form.ClientSize.Width, form.ClientSize.Height);
            context.OutputMerger.SetTargets(renderTargetView);
            context.Rasterizer.SetViewports(viewport);

            //
            // Create the DirectX11 texture2D. This texture will be shared with the DirectX10 device.
            //
            // The DirectX10 device will be used to render text onto this texture.
            // DirectX11 will then draw this texture (blended) onto the screen.
            // The KeyedMutex flag is required in order to share this resource between the two devices.
            var textureD3D11 = new Texture2D(device11, new Texture2DDescription
            {
                Width = form.ClientSize.Width,
                Height = form.ClientSize.Height,
                MipLevels = 1,
                ArraySize = 1,
                Format = Format.B8G8R8A8_UNorm,
                SampleDescription = new SampleDescription(1, 0),
                Usage = ResourceUsage.Default,
                BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource,
                CpuAccessFlags = CpuAccessFlags.None,
                OptionFlags = ResourceOptionFlags.SharedKeyedmutex
            });

            // ---------------------------------------------------------------------------------------------
            // Setup a direct 3d version 10.1 adapter
            // ---------------------------------------------------------------------------------------------
            var device10 = new Device10(adapter1, SharpDX.Direct3D10.DeviceCreationFlags.BgraSupport, FeatureLevel.Level_10_0);

            // ---------------------------------------------------------------------------------------------
            // Setup Direct 2d
            // ---------------------------------------------------------------------------------------------

            // Direct2D Factory
            var factory2D = new SharpDX.Direct2D1.Factory(FactoryType.SingleThreaded, DebugLevel.Information);

            // Here we bind the texture we've created on our direct3d11 device through the direct3d10
            // to the direct 2d render target....
            var sharedResource = textureD3D11.QueryInterface<SharpDX.DXGI.Resource>();
            var textureD3D10 = device10.OpenSharedResource<SharpDX.Direct3D10.Texture2D>(sharedResource.SharedHandle);

            var surface = textureD3D10.AsSurface();
            var rtp = new RenderTargetProperties
                {
                    MinLevel = SharpDX.Direct2D1.FeatureLevel.Level_10,
                    Type = RenderTargetType.Hardware,
                    PixelFormat = new PixelFormat(Format.Unknown, AlphaMode.Premultiplied)
                };

            var renderTarget2D = new RenderTarget(factory2D, surface, rtp);
            var solidColorBrush = new SolidColorBrush(renderTarget2D, Colors.Red);

            // ---------------------------------------------------------------------------------------------------
            // Setup the rendering data
            // ---------------------------------------------------------------------------------------------------

            // Load Effect. This includes both the vertex and pixel shaders.
            // Also can include more than one technique.
            ShaderBytecode shaderByteCode = ShaderBytecode.CompileFromFile(
                "effectDx11.fx",
                "fx_5_0",
                ShaderFlags.EnableStrictness);

            var effect = new Effect(device11, shaderByteCode);

            // create triangle vertex data, making sure to rewind the stream afterward
            var verticesTriangle = new DataStream(VertexPositionColor.SizeInBytes * 3, true, true);
            verticesTriangle.Write(new VertexPositionColor(new Vector3(0.0f, 0.5f, 0.5f),new Color4(1.0f, 0.0f, 0.0f, 1.0f)));
            verticesTriangle.Write(new VertexPositionColor(new Vector3(0.5f, -0.5f, 0.5f),new Color4(0.0f, 1.0f, 0.0f, 1.0f)));
            verticesTriangle.Write(new VertexPositionColor(new Vector3(-0.5f, -0.5f, 0.5f),new Color4(0.0f, 0.0f, 1.0f, 1.0f)));

            verticesTriangle.Position = 0;

            // create the triangle vertex layout and buffer
            var layoutColor = new InputLayout(device11, effect.GetTechniqueByName("Color").GetPassByIndex(0).Description.Signature, VertexPositionColor.inputElements);
            var vertexBufferColor = new Buffer(device11, verticesTriangle, (int)verticesTriangle.Length, ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
            verticesTriangle.Close();

            // create overlay vertex data, making sure to rewind the stream afterward
            // Top Left of screen is -1, +1
            // Bottom Right of screen is +1, -1
            var verticesText = new DataStream(VertexPositionTexture.SizeInBytes * 4, true, true);
            verticesText.Write(new VertexPositionTexture(new Vector3(-1, 1, 0),new Vector2(0, 0f)));
            verticesText.Write(new VertexPositionTexture(new Vector3(1, 1, 0),new Vector2(1, 0)));
            verticesText.Write(new VertexPositionTexture(new Vector3(-1, -1, 0),new Vector2(0, 1)));
            verticesText.Write(new VertexPositionTexture(new Vector3(1, -1, 0),new Vector2(1, 1)));

            verticesText.Position = 0;

            // create the overlay vertex layout and buffer
            var layoutOverlay = new InputLayout(device11, effect.GetTechniqueByName("Overlay").GetPassByIndex(0).Description.Signature, VertexPositionTexture.inputElements);
            var vertexBufferOverlay = new Buffer(device11, verticesText, (int)verticesText.Length, ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
            verticesText.Close();

            // Think of the shared textureD3D10 as an overlay.
            // The overlay needs to show the 2d content but let the underlying triangle (or whatever)
            // show thru, which is accomplished by blending.
            var bsd = new BlendStateDescription();
            bsd.RenderTarget[0].IsBlendEnabled = true;
            bsd.RenderTarget[0].SourceBlend = BlendOption.SourceColor;
            bsd.RenderTarget[0].DestinationBlend = BlendOption.BlendFactor;
            bsd.RenderTarget[0].BlendOperation = BlendOperation.Add;
            bsd.RenderTarget[0].SourceAlphaBlend = BlendOption.One;
            bsd.RenderTarget[0].DestinationAlphaBlend = BlendOption.Zero;
            bsd.RenderTarget[0].AlphaBlendOperation = BlendOperation.Add;
            bsd.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;

            var blendStateTransparent = new BlendState(device11, bsd);

            // ---------------------------------------------------------------------------------------------------
            // Create and tesselate an ellipse
            // ---------------------------------------------------------------------------------------------------
            var center = new DrawingPointF(form.ClientSize.Width/2.0f, form.ClientSize.Height/2.0f);
            var ellipse = new EllipseGeometry(factory2D, new Ellipse(center, form.ClientSize.Width / 2.0f, form.ClientSize.Height / 2.0f));

            // Populate a PathGeometry from Ellipse tessellation
            var tesselatedGeometry = new PathGeometry(factory2D);
            _geometrySink = tesselatedGeometry.Open();

            // Force RoundLineJoin otherwise the tesselated looks buggy at line joins
            _geometrySink.SetSegmentFlags(PathSegment.ForceRoundLineJoin);

            // Tesselate the ellipse to our TessellationSink
            ellipse.Tessellate(1, this);

            _geometrySink.Close();

            // ---------------------------------------------------------------------------------------------------
            // Acquire the mutexes. These are needed to assure the device in use has exclusive access to the surface
            // ---------------------------------------------------------------------------------------------------

            var device10Mutex = textureD3D10.QueryInterface<KeyedMutex>();
            var device11Mutex = textureD3D11.QueryInterface<KeyedMutex>();

            // ---------------------------------------------------------------------------------------------------
            // Main rendering loop
            // ---------------------------------------------------------------------------------------------------

            bool first = true;

            RenderLoop
                .Run(form,
                     () =>
                         {
                             if(first)
                             {
                                 form.Activate();
                                 first = false;
                             }

                             // clear the render target to black
                             context.ClearRenderTargetView(renderTargetView, Colors.DarkSlateGray);

                             // Draw the triangle
                             context.InputAssembler.InputLayout = layoutColor;
                             context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
                             context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertexBufferColor, VertexPositionColor.SizeInBytes, 0));
                             context.OutputMerger.BlendState = null;
                             var currentTechnique = effect.GetTechniqueByName("Color");
                             for (var pass = 0; pass < currentTechnique.Description.PassCount; ++pass)
                             {
                                 using (var effectPass = currentTechnique.GetPassByIndex(pass))
                                 {
                                     System.Diagnostics.Debug.Assert(effectPass.IsValid, "Invalid EffectPass");
                                     effectPass.Apply(context);
                                 }
                                 context.Draw(3, 0);
                             };

                             // Draw Ellipse on the shared Texture2D
                             device10Mutex.Acquire(0, 100);
                             renderTarget2D.BeginDraw();
                             renderTarget2D.Clear(Colors.Black);
                             renderTarget2D.DrawGeometry(tesselatedGeometry, solidColorBrush);
                             renderTarget2D.DrawEllipse(new Ellipse(center, 200, 200), solidColorBrush, 20, null);
                             renderTarget2D.EndDraw();
                             device10Mutex.Release(0);

                             // Draw the shared texture2D onto the screen, blending the 2d content in
                             device11Mutex.Acquire(0, 100);
                             var srv = new ShaderResourceView(device11, textureD3D11);
                             effect.GetVariableByName("g_Overlay").AsShaderResource().SetResource(srv);
                             context.InputAssembler.InputLayout = layoutOverlay;
                             context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleStrip;
                             context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertexBufferOverlay, VertexPositionTexture.SizeInBytes, 0));
                             context.OutputMerger.BlendState = blendStateTransparent;
                             currentTechnique = effect.GetTechniqueByName("Overlay");

                             for (var pass = 0; pass < currentTechnique.Description.PassCount; ++pass)
                             {
                                 using (var effectPass = currentTechnique.GetPassByIndex(pass))
                                 {
                                     System.Diagnostics.Debug.Assert(effectPass.IsValid, "Invalid EffectPass");
                                     effectPass.Apply(context);
                                 }
                                 context.Draw(4, 0);
                             }
                             srv.Dispose();
                             device11Mutex.Release(0);

                             swapChain.Present(0, PresentFlags.None);
                         });

            // dispose everything
            vertexBufferColor.Dispose();
            vertexBufferOverlay.Dispose();
            layoutColor.Dispose();
            layoutOverlay.Dispose();
            effect.Dispose();
            shaderByteCode.Dispose();
            renderTarget2D.Dispose();
            swapChain.Dispose();
            device11.Dispose();
            device10.Dispose();
            textureD3D10.Dispose();
            textureD3D11.Dispose();
            factory1.Dispose();
            adapter1.Dispose();
            sharedResource.Dispose();
            factory2D.Dispose();
            surface.Dispose();
            solidColorBrush.Dispose();
            blendStateTransparent.Dispose();

            device10Mutex.Dispose();
            device11Mutex.Dispose();
        }
Exemplo n.º 5
0
        public void Start()
        {
            running = true;
            Task.Factory.StartNew(() =>
            {
                form                   = new SharpDX.Windows.RenderForm("Oculus UI Debug");
                form.Width             = 1024 + 16;
                form.Height            = 512 + 39;
                form.AllowUserResizing = false;

                // Create DirectX drawing device.
                SharpDX.Direct3D11.Device device = new Device(SharpDX.Direct3D.DriverType.Hardware, DeviceCreationFlags.Debug);

                // Create DirectX Graphics Interface factory, used to create the swap chain.
                Factory factory = new Factory();

                DeviceContext immediateContext = device.ImmediateContext;

                // Define the properties of the swap chain.
                SwapChainDescription swapChainDescription = new SwapChainDescription();
                swapChainDescription.BufferCount          = 1;
                swapChainDescription.IsWindowed           = true;
                swapChainDescription.OutputHandle         = form.Handle;
                swapChainDescription.SampleDescription    = new SampleDescription(1, 0);
                swapChainDescription.Usage                  = Usage.RenderTargetOutput | Usage.ShaderInput;
                swapChainDescription.SwapEffect             = SwapEffect.Sequential;
                swapChainDescription.Flags                  = SwapChainFlags.AllowModeSwitch;
                swapChainDescription.ModeDescription.Width  = 1024;
                swapChainDescription.ModeDescription.Height = 512;
                swapChainDescription.ModeDescription.Format = Format.R8G8B8A8_UNorm;
                swapChainDescription.ModeDescription.RefreshRate.Numerator   = 0;
                swapChainDescription.ModeDescription.RefreshRate.Denominator = 1;

                // Create the swap chain.
                SharpDX.DXGI.SwapChain swapChain = new SwapChain(factory, device, swapChainDescription);

                // Retrieve the back buffer of the swap chain.
                Texture2D backBuffer = swapChain.GetBackBuffer <Texture2D>(0);
                RenderTargetView backBufferRenderTargetView = new RenderTargetView(device, backBuffer);

                // Create a depth buffer, using the same width and height as the back buffer.
                Texture2DDescription depthBufferDescription = new Texture2DDescription();
                depthBufferDescription.Format            = Format.D32_Float;
                depthBufferDescription.ArraySize         = 1;
                depthBufferDescription.MipLevels         = 1;
                depthBufferDescription.Width             = 1024;
                depthBufferDescription.Height            = 512;
                depthBufferDescription.SampleDescription = new SampleDescription(1, 0);
                depthBufferDescription.Usage             = ResourceUsage.Default;
                depthBufferDescription.BindFlags         = BindFlags.DepthStencil;
                depthBufferDescription.CpuAccessFlags    = CpuAccessFlags.None;
                depthBufferDescription.OptionFlags       = ResourceOptionFlags.None;

                // Define how the depth buffer will be used to filter out objects, based on their distance from the viewer.
                DepthStencilStateDescription depthStencilStateDescription = new DepthStencilStateDescription();
                depthStencilStateDescription.IsDepthEnabled  = true;
                depthStencilStateDescription.DepthComparison = Comparison.Less;
                depthStencilStateDescription.DepthWriteMask  = DepthWriteMask.Zero;

                // Create the depth buffer.
                Texture2D depthBuffer               = new Texture2D(device, depthBufferDescription);
                DepthStencilView depthStencilView   = new DepthStencilView(device, depthBuffer);
                DepthStencilState depthStencilState = new DepthStencilState(device, depthStencilStateDescription);
                Viewport viewport = new Viewport(0, 0, 1024, 512, 0.0f, 1.0f);

                immediateContext.OutputMerger.SetDepthStencilState(depthStencilState);
                immediateContext.OutputMerger.SetRenderTargets(depthStencilView, backBufferRenderTargetView);
                immediateContext.Rasterizer.SetViewport(viewport);


                SharpDX.Toolkit.Graphics.GraphicsDevice gd = SharpDX.Toolkit.Graphics.GraphicsDevice.New(device);


                var blendStateDescription = new BlendStateDescription();

                blendStateDescription.AlphaToCoverageEnable = false;

                blendStateDescription.RenderTarget[0].IsBlendEnabled        = true;
                blendStateDescription.RenderTarget[0].SourceBlend           = BlendOption.SourceAlpha;
                blendStateDescription.RenderTarget[0].DestinationBlend      = BlendOption.InverseSourceAlpha;
                blendStateDescription.RenderTarget[0].BlendOperation        = BlendOperation.Add;
                blendStateDescription.RenderTarget[0].SourceAlphaBlend      = BlendOption.Zero;
                blendStateDescription.RenderTarget[0].DestinationAlphaBlend = BlendOption.Zero;
                blendStateDescription.RenderTarget[0].AlphaBlendOperation   = BlendOperation.Add;
                blendStateDescription.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;

                var blendState = SharpDX.Toolkit.Graphics.BlendState.New(gd, blendStateDescription);
                gd.SetBlendState(blendState);


                var resource = sharedTexture.QueryInterface <SharpDX.DXGI.Resource>();
                var texture  = device.OpenSharedResource <Texture2D>(resource.SharedHandle);

                var basicEffect = new SharpDX.Toolkit.Graphics.BasicEffect(gd);

                basicEffect.PreferPerPixelLighting = false;
                basicEffect.Texture = SharpDX.Toolkit.Graphics.Texture2D.New(gd, texture);

                basicEffect.TextureEnabled  = true;
                basicEffect.LightingEnabled = false;

                // background texture
                var backgroundTexture = SharpDX.Toolkit.Graphics.Texture2D.Load(gd, "Graphics/debug.png");
                var backEffect        = new SharpDX.Toolkit.Graphics.BasicEffect(gd);

                backEffect.PreferPerPixelLighting = false;
                backEffect.Texture = backgroundTexture;

                backEffect.TextureEnabled  = true;
                backEffect.LightingEnabled = false;



                var primitive = SharpDX.Toolkit.Graphics.GeometricPrimitive.Plane.New(gd, 2f, 2f, 1);

                // Retrieve the DXGI device, in order to set the maximum frame latency.
                using (SharpDX.DXGI.Device1 dxgiDevice = device.QueryInterface <SharpDX.DXGI.Device1>())
                {
                    dxgiDevice.MaximumFrameLatency = 1;
                }

                RenderLoop.Run(form, () =>
                {
                    immediateContext.ClearRenderTargetView(backBufferRenderTargetView, new Color4(1f, 0.5f, 0.3f, 1f));
                    immediateContext.ClearDepthStencilView(depthStencilView, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0);

                    backEffect.World      = basicEffect.World = Matrix.Identity;
                    backEffect.View       = basicEffect.View = Matrix.Identity;
                    backEffect.Projection = basicEffect.Projection = Matrix.Identity;

                    primitive.Draw(backEffect);
                    primitive.Draw(basicEffect);

                    swapChain.Present(0, PresentFlags.None);

                    if (!running)
                    {
                        form.Close();
                    }
                });
            });
        }