コード例 #1
0
        public AnimatedCursor(Context context, IRenderDevice device, iPipelineStateFactory stateFactory, iShaderFactory shaderFactory, iStorageFolder assets)
        {
            constantBuffer = device.CreateDynamicUniformBuffer <AnimatedConstantBuffer>("Animated cursor CB");

            PipelineStateDesc desc = createStateDesc(context);

            desc.premultipliedBlendingMaxAlpha();

            initState(stateFactory, shaderFactory, assets, "AniCursorVS.hlsl", "AniCursorPS.hlsl", "Animated cursor");

            stateFactory.apply(ref desc);
            pipelineState = device.CreatePipelineState(ref desc);

            pipelineState.GetStaticVariableByName(ShaderType.Vertex, "CursorCB").Set(constantBuffer);
            pipelineState.GetStaticVariableByName(ShaderType.Pixel, "CursorCB").Set(constantBuffer);

            bindings        = pipelineState.CreateShaderResourceBinding(true);
            textureVariable = bindings.GetVariableByName(ShaderType.Pixel, "g_Texture");

            animatedConstants = default;
            timers            = context.animation.timers;
            lastFrameSwitch   = timers[animationTimer];
            lastRendered      = lastFrameSwitch;
            frameDuration     = default;
            animationFrames   = 0;
        }
コード例 #2
0
ファイル: VrmacStateBase.cs プロジェクト: zeta1999/Vrmac
        static void setupDepthState(ref PipelineStateDesc desc, eShaderMacros macros)
        {
            // Enable depth for both opaque and transparent passes..
            desc.GraphicsPipeline.DepthStencilDesc.DepthEnable = true;
            desc.GraphicsPipeline.DepthStencilDesc.DepthFunc   = ComparisonFunction.Less;

            // ..and set it so the depth is written on opaque pass, but readonly on transparent one.
            // With some luck, this should allow early Z rejection on both passes, saving tremendous amount of pixel shader invocations and fillrate bandwidth.
            if (macros.HasFlag(eShaderMacros.OpaquePass))
            {
                desc.GraphicsPipeline.DepthStencilDesc.DepthWriteEnable = true;
            }
            else
            {
                desc.GraphicsPipeline.DepthStencilDesc.DepthWriteEnable = false;
                // desc.premultipliedAlphaBlending();

                RenderTargetBlendDesc blendDesc = new RenderTargetBlendDesc(false)
                {
                    BlendEnable = true,
                    SrcBlend    = BlendFactor.One,
                    DestBlend   = BlendFactor.InvSrcAlpha,

                    SrcBlendAlpha  = BlendFactor.One,
                    DestBlendAlpha = BlendFactor.One,
                    BlendOpAlpha   = BlendOperation.Max,
                };
                desc.GraphicsPipeline.BlendDesc.setRenderTarget(blendDesc);
            }
        }
コード例 #3
0
ファイル: MoreDrawCallsState.cs プロジェクト: zeta1999/Vrmac
        public MoreDrawCallsState(GpuResources res, IRenderDevice device, ref PipelineStateDesc desc, iPipelineStateFactory stateFactory, eShaderMacros macros) :
            base(res, device, ref desc, stateFactory, macros)
        {
            drawCallsBuffer = res.moreDrawCalls;

            drawCallsBuffer.resized.add(this, (DynamicBuffer buffer, int capacity) => dropResourceBindings());
        }
コード例 #4
0
ファイル: Nv12State.cs プロジェクト: zeta1999/Vrmac
        public Nv12State(IRenderDevice device, TextureFormat format, Nv12Texture[] textures, ref sDecodedVideoSize videoSize)
        {
            // Create the pipeline state
            var pso = new PipelineStateDesc(false);

            pso.GraphicsPipeline.DepthStencilDesc.DepthEnable = false;
            pso.GraphicsPipeline.RasterizerDesc.CullMode      = CullMode.None;
            pso.GraphicsPipeline.PrimitiveTopology            = PrimitiveTopology.TriangleList;
            pso.GraphicsPipeline.NumRenderTargets             = 1;
            pso.GraphicsPipeline.setRTVFormat(0, format);
            pso.ResourceLayout.DefaultVariableType = ShaderResourceVariableType.Static;

            var            compiler = device.GetShaderFactory();
            iStorageFolder assets   = StorageFolder.embeddedResources(System.Reflection.Assembly.GetExecutingAssembly(), resourceFolder);

            using (var psf = device.CreatePipelineStateFactory())
            {
                psf.setName("Video PSO");

                using (var vs = compiler.compileHlslFile(assets, "VideoVS.hlsl", ShaderType.Vertex))
                    psf.graphicsVertexShader(vs);

                using (var ps = compilePixelShader(compiler, assets))
                    psf.graphicsPixelShader(ps);

                psf.layoutVariable(ShaderType.Pixel, ShaderResourceVariableType.Dynamic, varTexture);

                var sampler = samplerDesc();
                psf.layoutStaticSampler(ShaderType.Pixel, ref sampler, varTexture);

                psf.apply(ref pso);
                pipelineState = device.CreatePipelineState(ref pso);
            }

            // Create resource binding and cache the variable
            binding         = pipelineState.CreateShaderResourceBinding(true);
            textureVariable = binding.GetVariableByName(ShaderType.Pixel, varTexture);

            // Copy views of the textures into array
            sourceTextures = new ITextureView[textures.Length];
            for (int i = 0; i < textures.Length; i++)
            {
                sourceTextures[i] = textures[i].view;
            }

            // Create GL viewport structure with weird values for cropping the video
            viewport = new Viewport(false)
            {
                TopLeftX = -videoSize.cropRect.left,
                // TopLeftY = videoSize.cropRect.top,
                // OpenGL uses opposite Y direction there.
                TopLeftY = videoSize.cropRect.bottom - videoSize.size.cy,
                Width    = videoSize.size.cx,
                Height   = videoSize.size.cy,
            };
        }
コード例 #5
0
ファイル: Utils.cs プロジェクト: zeta1999/Vrmac
        public static PipelineStateDesc createStateDesc(Context context)
        {
            PipelineStateDesc desc = new PipelineStateDesc(false);

            desc.setBufferFormats(context);

            desc.GraphicsPipeline.PrimitiveTopology            = PrimitiveTopology.TriangleStrip;
            desc.GraphicsPipeline.RasterizerDesc.CullMode      = CullMode.Back;
            desc.GraphicsPipeline.DepthStencilDesc.DepthEnable = false;
            return(desc);
        }
コード例 #6
0
ファイル: StatesCache.cs プロジェクト: zeta1999/Vrmac
        // Create PipelineStateDesc with some essential setup
        PipelineStateDesc createStateDesc()
        {
            PipelineStateDesc desc = new PipelineStateDesc(false);

            desc.GraphicsPipeline.NumRenderTargets = 1;
            desc.setBufferFormats(resources.context);

            desc.GraphicsPipeline.PrimitiveTopology            = PrimitiveTopology.TriangleList;
            desc.GraphicsPipeline.RasterizerDesc.CullMode      = CullMode.None;
            desc.GraphicsPipeline.DepthStencilDesc.DepthEnable = true;

            desc.ResourceLayout.DefaultVariableType = ShaderResourceVariableType.Static;
            return(desc);
        }
コード例 #7
0
        public RenderBase(IRenderDevice device, CSize renderTargetSize, SwapChainFormats formats, Vector4 borderColor, sDecodedVideoSize videoSize)
        {
            this.videoSize = videoSize;
            // Create vertex buffer
            vertexBuffer = createVideoVertexBuffer(device, renderTargetSize, ref videoSize);

            // Create pipeline state
            var pso = new PipelineStateDesc(false);

            pso.GraphicsPipeline.DepthStencilDesc.DepthEnable = false;
            pso.GraphicsPipeline.PrimitiveTopology            = PrimitiveTopology.TriangleList;
            pso.GraphicsPipeline.NumRenderTargets             = 1;
            pso.GraphicsPipeline.setRTVFormat(0, formats.color);
            pso.GraphicsPipeline.DSVFormat         = formats.depth;
            pso.ResourceLayout.DefaultVariableType = ShaderResourceVariableType.Static;

            var            compiler = device.GetShaderFactory();
            iStorageFolder assets   = StorageFolder.embeddedResources(System.Reflection.Assembly.GetExecutingAssembly(), resourceFolder);

            using (var psf = device.CreatePipelineStateFactory())
            {
                psf.setName("Video PSO");
                setupVideoInputLayout(psf);

                using (var vs = compiler.compileHlslFile(assets, "VideoVS.hlsl", ShaderType.Vertex))
                    psf.graphicsVertexShader(vs);

                (string uvMin, string uvMax) = videoUvCroppedRect(ref videoSize);
                string colorString = Utils.printFloat4(borderColor);
                using (var ps = compilePixelShader(compiler, assets, uvMin, uvMax, colorString))
                    psf.graphicsPixelShader(ps);

                psf.layoutVariable(ShaderType.Pixel, ShaderResourceVariableType.Dynamic, varTexture);

                var sampler = new SamplerDesc(false)
                {
                    MipFilter = FilterType.Point,
                };
                psf.layoutStaticSampler(ShaderType.Pixel, ref sampler, varTexture);

                psf.apply(ref pso);
                pipelineState = device.CreatePipelineState(ref pso);
            }

            // Create resource binding and cache the variable, we gonna need both on every frame rendered
            binding         = pipelineState.CreateShaderResourceBinding(true);
            textureVariable = binding.GetVariableByName(ShaderType.Pixel, varTexture);
        }
コード例 #8
0
ファイル: StatesCache.cs プロジェクト: zeta1999/Vrmac
        VrmacStateBase compileState(eShaderMacros macros)
        {
            using (var dev = resources.context.renderContext.device)
                using (var stateFactory = dev.CreatePipelineStateFactory())
                {
                    PipelineStateDesc desc = createStateDesc();
                    setupIdLayout(stateFactory);
                    compileShaders(dev, stateFactory, "draw", macros);

                    if (macros.HasFlag(eShaderMacros.FewDrawCalls))
                    {
                        return(new FewDrawCallsState(resources, dev, ref desc, stateFactory, macros));
                    }

                    return(new MoreDrawCallsState(resources, dev, ref desc, stateFactory, macros));
                }
        }
コード例 #9
0
        public StaticCursor(Context context, IRenderDevice device, iPipelineStateFactory stateFactory, iShaderFactory shaderFactory, iStorageFolder assets, IShader vs)
        {
            constantBuffer = device.CreateDynamicUniformBuffer <Vector4>("Cursor CB");

            PipelineStateDesc desc = createStateDesc(context);

            desc.premultipliedAlphaBlending();

            initState(stateFactory, shaderFactory, assets, vs, "CursorPS.hlsl", "Cursor");

            stateFactory.apply(ref desc);
            pipelineState = device.CreatePipelineState(ref desc);
            pipelineState.GetStaticVariableByName(ShaderType.Vertex, "CursorCB").Set(constantBuffer);

            bindings        = pipelineState.CreateShaderResourceBinding(true);
            textureVariable = bindings.GetVariableByName(ShaderType.Pixel, "g_Texture");

            position = default;
        }
コード例 #10
0
        public Blender(Context context, IRenderDevice device, byte samplesCount)
        {
            PipelineStateDesc desc = new PipelineStateDesc(false);

            desc.setBufferFormats(context);
            desc.premultipliedAlphaBlending();
            desc.GraphicsPipeline.PrimitiveTopology            = PrimitiveTopology.TriangleList;
            desc.GraphicsPipeline.RasterizerDesc.CullMode      = CullMode.None;
            desc.GraphicsPipeline.DepthStencilDesc.DepthEnable = false;

            iShaderFactory shaderFactory = device.GetShaderFactory();
            iStorageFolder assets        = StorageFolder.embeddedResources(Assembly.GetExecutingAssembly(), resourceSubfolder);

            using (iPipelineStateFactory stateFactory = device.CreatePipelineStateFactory())
            {
                stateFactory.layoutVariable(ShaderType.Pixel, ShaderResourceVariableType.Mutable, textureVarName);

                stateFactory.graphicsVertexShader(shaderFactory.compileShader(assets, "Blend", ShaderType.Vertex));

                ShaderSourceInfo ssi;
                string           src;
                if (RuntimeEnvironment.operatingSystem == eOperatingSystem.Windows)
                {
                    ssi = new ShaderSourceInfo(ShaderType.Pixel, ShaderSourceLanguage.Hlsl);
                    src = "BlendPS.hlsl";
                }
                else
                {
                    ssi = new ShaderSourceInfo(ShaderType.Pixel, ShaderSourceLanguage.Glsl);
                    ssi.combinedTextureSamplers = true;
                    src = "BlendPS.glsl";
                }

                string name = $"BlendPS { samplesCount }x";
                var    ps   = shaderFactory.compileFromFile(assets, src, ssi, name, shaderMacros(samplesCount));
                stateFactory.graphicsPixelShader(ps);

                stateFactory.apply(ref desc);
                pipelineState = device.CreatePipelineState(ref desc);
            }
            this.samplesCount = samplesCount;
        }
コード例 #11
0
ファイル: VrmacStateBase.cs プロジェクト: zeta1999/Vrmac
        public VrmacStateBase(GpuResources resources, IRenderDevice device, ref PipelineStateDesc desc, iPipelineStateFactory stateFactory, eShaderMacros macros)
        {
            this.resources = resources;
            shaderMacros   = macros;

            layoutUniforms(stateFactory);
            stateFactory.setName($"2D state { macros }");

            stateFactory.layoutVariable(ShaderType.Vertex, ShaderResourceVariableType.Mutable, varPaletteTexture);
            stateFactory.layoutVariable(ShaderType.Pixel, ShaderResourceVariableType.Mutable, varPaletteTexture);

            if (macros.HasFlag(eShaderMacros.TextureAtlas))
            {
                stateFactory.layoutVariable(ShaderType.Pixel, ShaderResourceVariableType.Mutable, varSpriteAtlas);
                SamplerDesc samplerDesc = new SamplerDesc(false);
                stateFactory.layoutStaticSampler(ShaderType.Pixel, ref samplerDesc, varSpriteAtlas);

                resources.context.drawDevice.textureAtlas.resized.add(this, dropResourceBindings);
            }

            if (macros.HasFlag(eShaderMacros.TextRendering))
            {
                stateFactory.layoutVariable(ShaderType.Pixel, ShaderResourceVariableType.Mutable, varGrayscaleFontAtlas);
                SamplerDesc samplerDesc = new SamplerDesc(false);
                stateFactory.layoutStaticSampler(ShaderType.Pixel, ref samplerDesc, varGrayscaleFontAtlas);

                stateFactory.layoutVariable(ShaderType.Pixel, ShaderResourceVariableType.Mutable, varCleartypeFontAtlas);

                resources.initTextCBuffer();
            }

            declareResources(stateFactory);

            stateFactory.apply(ref desc);
            setupDepthState(ref desc, macros);

            pipelineState = device.CreatePipelineState(ref desc);

            resources.context.swapChainResized.add(this, (CSize s, double d) => dropResourceBindings());
            resources.paletteTexture.textureResized.add(this, dropResourceBindings);
        }
コード例 #12
0
        public MonoCursor(Context context, IRenderDevice device, iPipelineStateFactory stateFactory, iShaderFactory shaderFactory, iStorageFolder assets, IShader vs)
        {
            constantBuffer = device.CreateDynamicUniformBuffer <Vector4>("Cursor CB");

            PipelineStateDesc desc = createStateDesc(context);

            // === First pass, setup that weird blending to invert colors ===
            RenderTargetBlendDesc blendDesc = new RenderTargetBlendDesc(false)
            {
                BlendEnable = true,
                SrcBlend    = BlendFactor.InvDestColor,
                DestBlend   = BlendFactor.Zero,
            };

            desc.GraphicsPipeline.BlendDesc.setRenderTarget(blendDesc);
            initState(stateFactory, shaderFactory, assets, vs, "CursorMaskPS.hlsl", "Invert bits");

            stateFactory.apply(ref desc);
            psoInvert = device.CreatePipelineState(ref desc);
            psoInvert.GetStaticVariableByName(ShaderType.Vertex, "CursorCB").Set(constantBuffer);

            bindingsInvert        = psoInvert.CreateShaderResourceBinding(true);
            textureVariableInvert = bindingsInvert.GetVariableByName(ShaderType.Pixel, "g_Texture");

            // === Second pass, normal alpha blending ===
            desc.premultipliedAlphaBlending();
            initState(stateFactory, shaderFactory, assets, vs, "CursorColorPS.hlsl", "Monochrome cursor");

            stateFactory.apply(ref desc);
            psoRgb = device.CreatePipelineState(ref desc);
            psoRgb.GetStaticVariableByName(ShaderType.Vertex, "CursorCB").Set(constantBuffer);

            bindingsRgb        = psoRgb.CreateShaderResourceBinding(true);
            textureVariableRgb = bindingsRgb.GetVariableByName(ShaderType.Pixel, "g_Texture");

            position = default;
        }
コード例 #13
0
 public FewDrawCallsState(GpuResources res, IRenderDevice device, ref PipelineStateDesc desc, iPipelineStateFactory stateFactory, eShaderMacros macros) :
     base(res, device, ref desc, stateFactory, macros)
 {
     constantBuffer = res.fewDrawCalls;
     pipelineState.GetStaticVariableByName(ShaderType.Vertex, "DrawCallsCBuffer").Set(constantBuffer);
 }
コード例 #14
0
        void createPipelineState(IRenderDevice device, iStorageFolder assets)
        {
            PipelineStateDesc PSODesc = new PipelineStateDesc(false);

            PSODesc.setBufferFormats(context);

            // Primitive topology defines what kind of primitives will be rendered by this pipeline state
            PSODesc.GraphicsPipeline.PrimitiveTopology = PrimitiveTopology.TriangleList;
            // Cull back faces
            PSODesc.GraphicsPipeline.RasterizerDesc.CullMode = CullMode.Back;
            // Enable depth testing
            PSODesc.GraphicsPipeline.DepthStencilDesc.DepthEnable = true;

            iShaderFactory shaderFactory = device.GetShaderFactory();

            // We won't be using the factory object after this, `using` to release the COM interface once finished
            using (iPipelineStateFactory stateFactory = device.CreatePipelineStateFactory())
            {
                stateFactory.setName("Cube PSO");

                // Compile the two shaders
                ShaderSourceInfo sourceInfo = new ShaderSourceInfo(ShaderType.Vertex, ShaderSourceLanguage.Hlsl);
                sourceInfo.combinedTextureSamplers = true;                  // This appears to be the requirement of OpenGL backend.

                // In this tutorial, we will load shaders from resources embedded into this .NET DLL.
                var vs = shaderFactory.compileFromFile(assets, "cube.vsh", sourceInfo, "Cube VS");
                stateFactory.graphicsVertexShader(vs);

                // Create dynamic uniform buffer that will store our transformation matrix. Dynamic buffers can be frequently updated by the CPU.
                BufferDesc CBDesc = new BufferDesc(false);
                CBDesc.uiSizeInBytes  = Marshal.SizeOf <Matrix4x4>();
                CBDesc.Usage          = Usage.Dynamic;
                CBDesc.BindFlags      = BindFlags.UniformBuffer;
                CBDesc.CPUAccessFlags = CpuAccessFlags.Write;
                vsConstants           = device.CreateBuffer(CBDesc, "VS constants CB");

                // Create a pixel shader
                sourceInfo.shaderType = ShaderType.Pixel;

                var ps = shaderFactory.compileFromFile(assets, "cube.psh", sourceInfo, "Cube PS");
                stateFactory.graphicsPixelShader(ps);

                // Define vertex shader input layout

                // Attribute 0 - vertex position
                LayoutElement elt = new LayoutElement(false)
                {
                    InputIndex    = 0,
                    BufferSlot    = 0,
                    NumComponents = 3,
                    ValueType     = GpuValueType.Float32,
                    IsNormalized  = false
                };
                stateFactory.graphicsLayoutElement(elt);
                // Attribute 1 - texture coordinates
                elt.InputIndex    = 1;
                elt.NumComponents = 2;
                stateFactory.graphicsLayoutElement(elt);

                // Define variable type that will be used by default
                PSODesc.ResourceLayout.DefaultVariableType = ShaderResourceVariableType.Static;
                // Shader variables should typically be mutable, which means they are expected to change on a per-instance basis
                stateFactory.layoutVariable(ShaderType.Pixel, ShaderResourceVariableType.Mutable, "g_Texture");

                // Define static sampler for g_Texture. Static samplers should be used whenever possible.
                // The default constructor is good enough, it sets FilterType.Linear and TextureAddressMode.Clamp for all 3 coordinates.
                SamplerDesc samplerDesc = new SamplerDesc(false);
                stateFactory.layoutStaticSampler(ShaderType.Pixel, ref samplerDesc, "g_Texture");

                stateFactory.apply(ref PSODesc);
                pipelineState = device.CreatePipelineState(ref PSODesc);
            }

            // Since we did not explicitly specify the type for 'Constants' variable, default
            // type (SHADER_RESOURCE_VARIABLE_TYPE_STATIC) will be used. Static variables never
            // change and are bound directly through the pipeline state object.
            pipelineState.GetStaticVariableByName(ShaderType.Vertex, "Constants").Set(vsConstants);

            // Since we are using mutable variable, we must create a shader resource binding object
            // http://diligentgraphics.com/2016/03/23/resource-binding-model-in-diligent-engine-2-0/
            resourceBinding = pipelineState.CreateShaderResourceBinding(true);
        }
コード例 #15
0
        public TeapotResources(Context context, IRenderDevice device)
        {
            PipelineStateDesc PSODesc = new PipelineStateDesc(false);

            PSODesc.setBufferFormats(context);

            // Primitive topology defines what kind of primitives will be rendered by this pipeline state
            PSODesc.GraphicsPipeline.PrimitiveTopology = PrimitiveTopology.TriangleList;
            // Cull back faces
            PSODesc.GraphicsPipeline.RasterizerDesc.CullMode = CullMode.Back;
            // Enable depth testing
            PSODesc.GraphicsPipeline.DepthStencilDesc.DepthEnable = true;

            iShaderFactory shaderFactory = device.GetShaderFactory();

            // We won't be using the device object after this, `using` is to release the COM interface once finished
            using (iPipelineStateFactory stateFactory = device.CreatePipelineStateFactory())
            {
                stateFactory.setName("Teapot PSO");

                // Compile the two shaders
                ShaderSourceInfo sourceInfo = new ShaderSourceInfo(ShaderType.Vertex, ShaderSourceLanguage.Hlsl);
                sourceInfo.combinedTextureSamplers = true;                  // This appears to be the requirement of OpenGL backend.

                // In this tutorial, we will load shaders from resources embedded into this .NET DLL.
                iStorageFolder resources = StorageFolder.embeddedResources(Assembly.GetExecutingAssembly(), resourcesFolder);
                var            vs        = shaderFactory.compileFromFile(resources, "TeapotVS.hlsl", sourceInfo, "Teapot VS");
                stateFactory.graphicsVertexShader(vs);

                // Create dynamic uniform buffer that will store our transformation matrix. Dynamic buffers can be frequently updated by the CPU.
                vsConstants = device.CreateDynamicUniformBuffer <VsConstants>("VS constants CB");

                // Create a pixel shader
                sourceInfo.shaderType = ShaderType.Pixel;
                var ps = shaderFactory.compileFromFile(resources, "TeapotPS.hlsl", sourceInfo, "Teapot PS");
                stateFactory.graphicsPixelShader(ps);

                // Define vertex shader input layout

                // Attribute 0 - vertex position
                LayoutElement elt = new LayoutElement(false)
                {
                    InputIndex    = 0,
                    BufferSlot    = 0,
                    NumComponents = 3,
                    ValueType     = GpuValueType.Float32,
                    IsNormalized  = false
                };
                stateFactory.graphicsLayoutElement(elt);

                // Attribute 1 - normals, they are generated by STL loader because we ask for them.
                elt.InputIndex    = 1;
                elt.NumComponents = 3;
                stateFactory.graphicsLayoutElement(elt);

                // Define variable type that will be used by default
                PSODesc.ResourceLayout.DefaultVariableType = ShaderResourceVariableType.Static;

                stateFactory.apply(ref PSODesc);
                pipelineState = device.CreatePipelineState(ref PSODesc);
            }

            // Since we did not explicitly specify the type for 'Constants' variable, default
            // type (SHADER_RESOURCE_VARIABLE_TYPE_STATIC) will be used. Static variables never
            // change and are bound directly through the pipeline state object.
            pipelineState.GetStaticVariableByName(ShaderType.Vertex, "Constants").Set(vsConstants);

            // Create a shader resource binding object and bind all static resources in it
            resourceBinding = pipelineState.CreateShaderResourceBinding(true);
        }
コード例 #16
0
        protected override void createResources(IRenderDevice device)
        {
            // Diligent Engine can use HLSL source on all supported platforms.
            // It will convert HLSL to GLSL in OpenGL mode, while Vulkan backend will compile it directly to SPIRV.
            string VSSource = @"
struct PSInput 
{ 
    float4 Pos   : SV_POSITION; 
    float3 Color : COLOR; 
};

void main( in uint VertId : SV_VertexID, out PSInput PSIn ) 
{
    float4 Pos[3];
    Pos[0] = float4(-0.5, -0.5, 0.0, 1.0);
    Pos[1] = float4( 0.0, +0.5, 0.0, 1.0);
    Pos[2] = float4(+0.5, -0.5, 0.0, 1.0);

    float3 Col[3];
    Col[0] = float3(1.0, 0.0, 0.0); // red
    Col[1] = float3(0.0, 1.0, 0.0); // green
    Col[2] = float3(0.0, 0.0, 1.0); // blue

    PSIn.Pos   = Pos[VertId];
    PSIn.Color = Col[VertId];
}";

            string            PSSource = @"
struct PSInput 
{ 
    float4 Pos   : SV_POSITION; 
    float3 Color : COLOR; 
};

struct PSOutput
{ 
    float4 Color : SV_TARGET; 
};

void main( in PSInput PSIn, out PSOutput PSOut )
{
    PSOut.Color = float4(PSIn.Color.rgb, 1.0);
}
";
            PipelineStateDesc PSODesc  = new PipelineStateDesc(false);

            PSODesc.setBufferFormats(context);

            // Primitive topology defines what kind of primitives will be rendered by this pipeline state
            PSODesc.GraphicsPipeline.PrimitiveTopology = PrimitiveTopology.TriangleList;
            // No back face culling for this tutorial
            PSODesc.GraphicsPipeline.RasterizerDesc.CullMode = CullMode.None;
            // Disable depth testing
            PSODesc.GraphicsPipeline.DepthStencilDesc.DepthEnable = false;

            iShaderFactory shaderFactory = device.GetShaderFactory();

            // We won't be using the device object after this, `using` is to release the COM interface once finished
            using (iPipelineStateFactory stateFactory = device.CreatePipelineStateFactory())
            {
                // Compile the two shaders
                ShaderSourceInfo sourceInfo = new ShaderSourceInfo(ShaderType.Vertex, ShaderSourceLanguage.Hlsl);
                sourceInfo.combinedTextureSamplers = true;                  // This appears to be the requirement of OpenGL backend.

                using (var vs = shaderFactory.compileFromSource(VSSource, sourceInfo))
                    stateFactory.graphicsVertexShader(vs);

                sourceInfo.shaderType = ShaderType.Pixel;
                using (var ps = shaderFactory.compileFromSource(PSSource, sourceInfo))
                    stateFactory.graphicsPixelShader(ps);

                stateFactory.apply(ref PSODesc);

                pipelineState = device.CreatePipelineState(ref PSODesc);
            }
        }