public void EmptyShaderReflectionTest()
        {
            byte[] vertexByteCode;
            byte[] framentByteCode;
            {
                var vertexShaderMain = new Function(Spv.FunctionControl.CreateNone(), new TypeFunction()
                {
                    ReturnType = SpirvTypeBase.Void
                }, "main")
                                       .SetUp(_ => _
                                              .ThenLabel()
                                              .ThenReturn()
                                              );
                var shader = new ShaderReflection()
                             .WithCapability(Capability.Shader())
                             .WithExtInstImport("GLSL.std.450")
                             .WithMemoryModel(AddressingModel.Logical(), MemoryModel.GLSL450())
                             .WithEntryPoint(ExecutionModel.Vertex(), vertexShaderMain)
                             .BuildShader();

                vertexByteCode = shader.Build();
            }
            {
                var fragmentShaderMain = new Function(Spv.FunctionControl.CreateNone(), new TypeFunction()
                {
                    ReturnType = SpirvTypeBase.Void
                }, "main")
                                         .SetUp(_ => _
                                                .ThenLabel()
                                                .ThenReturn()
                                                );

                var shader = new ShaderReflection()
                             .WithCapability(Capability.Shader())
                             .WithExtInstImport("GLSL.std.450")
                             .WithMemoryModel(AddressingModel.Logical(), MemoryModel.GLSL450())
                             .WithEntryPoint(ExecutionModel.Fragment(), fragmentShaderMain)
                             .BuildShader();

                framentByteCode = shader
                                  .Build();
            }

            var shaders = ResourceFactory.CreateFromSpirv(
                new ShaderDescription(ShaderStages.Vertex, vertexByteCode, "main"),
                new ShaderDescription(ShaderStages.Fragment, framentByteCode, "main"));

            var readRenderTargetPixel = RenderQuad(shaders);

            Assert.AreEqual(new RgbaByte(0, 0, 0, 255), readRenderTargetPixel);
        }
        public void GreenQuadReflectionTest()
        {
            byte[] vertexByteCode;
            byte[] framentByteCode;
            {
                var const_1f = new Constant(-1.0f);
                var const1f  = new Constant(1.0f);
                var const0f  = new Constant(0.0f);
                var const0i  = new Constant(0);

                var arrayType = new TypeArray(SpirvTypeBase.Vec4, 4);
                var a         = new ConstantComposite(SpirvTypeBase.Vec4, const_1f, const1f, const0f, const1f);
                var b         = new ConstantComposite(SpirvTypeBase.Vec4, const1f, const1f, const1f, const1f);
                var c         = new ConstantComposite(SpirvTypeBase.Vec4, const_1f, const_1f, const0f, const1f);
                var d         = new ConstantComposite(SpirvTypeBase.Vec4, const1f, const_1f, const1f, const1f);
                var positions = new ConstantComposite(arrayType, a, b, c, d);

                var clipArrayType = new TypeArray(SpirvTypeBase.Float, 1);
                var gl_PerVertex  = new TypeStruct("gl_PerVertex",
                                                   new TypeStructureField(SpirvTypeBase.Vec4, "gl_Position")
                                                   .WithDecoration(Decoration.BuiltIn(BuiltIn.Position())),
                                                   new TypeStructureField(SpirvTypeBase.Float, "gl_PointSize")
                                                   .WithDecoration(Decoration.BuiltIn(BuiltIn.PointSize())),
                                                   new TypeStructureField(clipArrayType, "gl_ClipDistance")
                                                   .WithDecoration(Decoration.BuiltIn(BuiltIn.ClipDistance())),
                                                   new TypeStructureField(clipArrayType, "gl_CullDistance")
                                                   .WithDecoration(Decoration.BuiltIn(BuiltIn.CullDistance()))
                                                   ).WithDecoration(Decoration.Block());
                var outputVar = new Variable(gl_PerVertex.MakePointer(StorageClass.Output()), StorageClass.Output(), null, "");

                var localVar = new Variable(
                    arrayType.MakePointer(StorageClass.Function()),
                    StorageClass.Function(), null, "indexable");
                Node positionPointer = new AccessChain(SpirvTypeBase.Vec4.MakePointer(StorageClass.Output()), outputVar, new[] { const0i });
                var  glVertexIndex   = Variable.gl_VertexIndex();
                Node position        = new Load(SpirvTypeBase.Vec4,
                                                new AccessChain(SpirvTypeBase.Vec4.MakePointer(StorageClass.Function()), localVar, new Node[]
                {
                    new Load(SpirvTypeBase.Int, glVertexIndex, null)
                }), null);
                var vertexShaderMain = new Function(Spv.FunctionControl.Enumerant.None, new TypeFunction()
                {
                    ReturnType = SpirvTypeBase.Void
                }, "main")
                                       .SetUp(_ => _
                                              .ThenLabel()
                                              .ThenStore(localVar, positions, null)
                                              .ThenStore(positionPointer, position, null)
                                              .ThenReturn()
                                              );
                var reflection = new ShaderReflection()
                                 .WithCapability(Capability.Shader())
                                 .WithExtInstImport("GLSL.std.450")
                                 .WithMemoryModel(AddressingModel.Logical(), MemoryModel.GLSL450())
                                 .WithEntryPoint(ExecutionModel.Vertex(), vertexShaderMain, "main");
                var shader = reflection
                             .BuildShader();

                vertexByteCode = shader.Build();

                Console.WriteLine("-----------------------");
                Node node = reflection.EntryPointInstructions.First().Value;
                while (node != null)
                {
                    Console.WriteLine($".Then(new {node})");
                    node = node.GetNext();
                }
                //var vertexSource = @"#version 450
                //#extension GL_KHR_vulkan_glsl : enable

                //const vec4 QuadInfos[4] =
                //{
                //    vec4(-1, 1, 0, 1),
                //    vec4(1, 1, 1, 1),
                //    vec4(-1, -1, 0, 1),
                //    vec4(1, -1, 1, 1),
                //};

                //void main()
                //{
                //    gl_Position = QuadInfos[gl_VertexIndex];
                //}";
                //vertexByteCode = ShaderTestBase.CompileToBytecode(vertexSource, ShaderStages.Vertex, true, true);
            }
            {
                var const0f  = new Constant(0.0f);
                var const1f  = new Constant(1.0f);
                var redColor = new ConstantComposite(SpirvTypeBase.Vec4, const0f, const1f, const0f, const1f);
                var v        = new Variable(SpirvTypeBase.Vec4.MakePointer(StorageClass.Output()), StorageClass.Output(), null, "fsout_Color0")
                {
                    Location = 0
                };
                var fragmentShaderMain = new Function(Spv.FunctionControl.Enumerant.None, new TypeFunction(SpirvTypeBase.Void), "main")
                                         .SetUp(_ => _
                                                .ThenLabel()
                                                .ThenStore(v, redColor, null)
                                                .ThenReturn()
                                                );

                var reflection = new ShaderReflection()
                                 .WithCapability(Capability.Shader())
                                 .WithExtInstImport("GLSL.std.450")
                                 .WithMemoryModel(AddressingModel.Logical(), MemoryModel.GLSL450())
                                 .WithEntryPoint(ExecutionModel.Fragment(), fragmentShaderMain, "main")
                                 .WithExecutionMode(fragmentShaderMain, ExecutionMode.OriginUpperLeft());

                var shader = reflection
                             .BuildShader();

                framentByteCode = shader
                                  .Build();

                Console.WriteLine("-----------------------");
                Node node = reflection.EntryPointInstructions.First().Value;
                while (node != null)
                {
                    Console.WriteLine($".Then(new {node})");
                    node = node.GetNext();
                }

                //    var fragmentSource = @"#version 450

                //layout(location = 0) out vec4 fsout_Color0;

                //void main()
                //{
                //    fsout_Color0 = vec4(0,1,0,1);
                //}";
                //    framentByteCode = ShaderTestBase.CompileToBytecode(fragmentSource, ShaderStages.Fragment, true, true);
            }

            {
                var glsl = Veldrid.SPIRV.SpirvCompilation.CompileVertexFragment(vertexByteCode, framentByteCode,
                                                                                CrossCompileTarget.GLSL);
                Console.WriteLine(glsl.VertexShader);
                Console.WriteLine(glsl.FragmentShader);
            }

            var shaders = ResourceFactory.CreateFromSpirv(
                new ShaderDescription(ShaderStages.Vertex, vertexByteCode, "main"),
                new ShaderDescription(ShaderStages.Fragment, framentByteCode, "main"));

            var readRenderTargetPixel = RenderQuad(shaders);

            Assert.AreEqual(new RgbaByte(0, 255, 0, 255), readRenderTargetPixel);
        }