public void FrameStart()
        {
            //clear depth to InverseDepth.Far
            CommandBuffer tmpcmd = new CommandBuffer();

            for (int i = 0; i < Engine.EyeCount; i++)
            {
                if (firstRun)
                {
                    RenderState tmpState = new RenderState(views[i].gbuffer, null, null, null, true, false, DepthFunc.Always, InverseDepth.Far, InverseDepth.Near, BlendFactor.One, BlendFactor.OneMinusSrcAlpha, Vector4.Zero, InverseDepth.ClearDepth, CullFaceMode.Back);
                    tmpcmd.SetRenderState(tmpState);
                    tmpcmd.Clear(false, true);
                    firstRun = false;
                }

                //copy depth buffer into top of Hi-Z chain
                tmpcmd.SetRenderState(views[i].copyState);
                tmpcmd.Barrier(BarrierType.All);
                tmpcmd.Dispatch(views[i].depthBuf.Width / 8, views[i].depthBuf.Height / 8, 1);
                tmpcmd.Barrier(BarrierType.All);
                tmpcmd.Submit();

                //build mip pyramid
                unsafe
                {
                    //return;
                    int w = views[i].depthBuf.Width / 2;
                    int h = views[i].depthBuf.Height / 2;
                    for (int j = 1; j < views[i].hiZView.Length; j++)
                    {
                        int *p = (int *)HiZMapUBO.Update();
                        p[0] = j - 1;
                        HiZMapUBO.UpdateDone();

                        tmpcmd.Reset();
                        tmpcmd.SetRenderState(views[i].mipchainState);
                        tmpcmd.Barrier(BarrierType.ShaderImageAccess | BarrierType.BufferUpdate);
                        tmpcmd.Dispatch(w / 8 + 1, h / 8 + 1, 1);
                        tmpcmd.Barrier(BarrierType.ShaderImageAccess | BarrierType.BufferUpdate);
                        tmpcmd.Submit();

                        w = w / 2;
                        h = h / 2;
                    }
                }
            }
        }