Пример #1
0
        protected void EmitShaderSetup(
            EmitContextHLSL hlslContext,
            string profile,
            string stageName,
            string prefix)
        {
            var hlslSpan = hlslContext.Span;

            var bytecode = hlslContext.Compile(profile);

            InitBlock.AppendComment(hlslContext.Span);

            if (bytecode != null && bytecode.Length > 0)
            {
                EmitTarget.ShaderBytecodeCallback(prefix, bytecode);
            }

            var bytecodeLengthVal = InitBlock.Temp(
                "bytecodeSize",
                InitBlock.LiteralU32(
                    (UInt32)bytecode.Length));
            var bytecodeVal = InitBlock.Temp(
                "bytecode",
                InitBlock.LiteralData(bytecode));

            // Terrible hack - save off vals in case of vertex shader... :(
            // This is required because creating an Input Layout
            // requires VS bytecode... for some reason...
            if (prefix == "VS")
            {
                EmitPass.VertexShaderBytecodeVal     = bytecodeVal;
                EmitPass.VertexShaderBytecodeSizeVal = bytecodeLengthVal;
            }


            var shaderType = EmitTarget.GetOpaqueType(
                string.Format("ID3D11{0}Shader*", stageName));
            var shaderNull = EmitTarget.GetNullPointer(shaderType);

            _shaderField = EmitClass.AddPrivateField(
                shaderType,
                string.Format("_{0}Shader", stageName));

            InitBlock.SetArrow(
                CtorThis,
                _shaderField,
                shaderNull);

            var classLinkageNull = EmitTarget.GetNullPointer(
                EmitTarget.GetOpaqueType("ID3D11ClassLinkage*"));

            InitBlock.CallCOM(
                CtorDevice,
                "ID3D11Device",
                string.Format("Create{0}Shader", stageName),
                bytecodeVal,
                bytecodeLengthVal,
                classLinkageNull,
                InitBlock.GetArrow(CtorThis, _shaderField).GetAddress());

            DtorBlock.CallCOM(
                DtorBlock.GetArrow(DtorThis, _shaderField),
                "IUnknown",
                "Release");
        }
Пример #2
0
        public override void EmitImplSetup()
        {
            var uniformElement = GetElement("Uniform");
            var iaElement      = GetElement("AssembledVertex");

            _vertexIDAttr   = GetAttribute(iaElement, "IA_VertexID").Attribute;
            _instanceIDAttr = GetAttribute(iaElement, "IA_InstanceID").Attribute;

            _info[_vertexIDAttr] = new IndexSourceInfo(_vertexIDAttr.Range)
            {
                InputSlotClass = InitBlock.Enum32("D3D11_INPUT_CLASSIFICATION", "D3D11_INPUT_PER_VERTEX_DATA", D3D11_INPUT_CLASSIFICATION.D3D11_INPUT_PER_VERTEX_DATA),
                StepRate       = 0
            };

            _info[_instanceIDAttr] = new IndexSourceInfo(_instanceIDAttr.Range)
            {
                InputSlotClass = InitBlock.Enum32("D3D11_INPUT_CLASSIFICATION", "D3D11_INPUT_PER_INSTANCE_DATA", D3D11_INPUT_CLASSIFICATION.D3D11_INPUT_PER_INSTANCE_DATA),
                StepRate       = 1
            };

            InitBlock.AppendComment("D3D11 Input Assembler");

            var inputElementInits = (from a in iaElement.Attributes
                                     where a.IsOutput
                                     let name = SharedHLSL.MapName(a)
                                                let attrInfo = TryDecomposeAttr(a.Range, a)
                                                               where attrInfo != null
                                                               from e in DeclareInputElements(InitBlock, name, attrInfo)
                                                               select e).ToArray();

            if (_inputElementCount != 0)
            {
                var inputElementDescsVal = InitBlock.Temp(
                    "inputElementDescs",
                    InitBlock.Array(
                        EmitTarget.GetBuiltinType("D3D11_INPUT_ELEMENT_DESC"),
                        inputElementInits));

                var inputLayoutPointerType = EmitTarget.GetOpaqueType("ID3D11InputLayout*");
                inputLayoutField = EmitClass.AddPrivateField(
                    inputLayoutPointerType,
                    "_inputLayout");
                InitBlock.SetArrow(
                    CtorThis,
                    inputLayoutField,
                    EmitTarget.GetNullPointer(inputLayoutPointerType));

                InitBlock.CallCOM(
                    CtorDevice,
                    "ID3D11Device",
                    "CreateInputLayout",
                    inputElementDescsVal.GetAddress(),
                    InitBlock.LiteralU32((UInt32)_inputElementCount),
                    EmitPass.VertexShaderBytecodeVal,
                    EmitPass.VertexShaderBytecodeSizeVal,
                    InitBlock.GetArrow(CtorThis, inputLayoutField).GetAddress());

                DtorBlock.CallCOM(
                    DtorBlock.GetArrow(DtorThis, inputLayoutField),
                    "IUnknown",
                    "Release");
            }
        }
Пример #3
0
        //



        public override void EmitImplSetup()
        {
            var uniformElement  = GetElement("Uniform");
            var rasterVertex    = GetElement("RasterVertex");
            var fragmentElement = GetElement("Fragment");
            var pixelElement    = GetElement("Pixel");

            // Find all render targets:

            renderTargetAttributes = (from a in pixelElement.Attributes
                                      where a.Exp != null
                                      where a.IsOutput
                                      select a).ToArray();
            renderTargetCount = renderTargetAttributes.Length;

            // Depth-stencil view

            depthStencilViewAttribute = GetAttribute(uniformElement, "depthStencilView");


            // Compute the setup required by the OM


            // Blending stuff
            var blendStateType = EmitTarget.GetOpaqueType("ID3D11BlendState*");

            blendStateField = EmitClass.AddPrivateField(
                blendStateType,
                "_blendState");


            _renderTargetBlendDescs = new TargetBlendDesc[renderTargetCount];
            _renderTargetSources    = new SourceInfo[renderTargetCount];
            for (int ii = 0; ii < renderTargetCount; ++ii)
            {
                DecomposeAttr(renderTargetAttributes[ii], ii);
            }

            var rtBlendDescType = EmitTarget.GetBuiltinType("D3D11_RENDER_TARGET_BLEND_DESC");
            var blendSpecVals   = (from desc in _renderTargetBlendDescs
                                   select InitBlock.Struct(
                                       "D3D11_RENDER_TARGET_BLEND_DESC",
                                       InitBlock.LiteralBool(desc.blendEnable),
                                       InitBlock.Enum32(desc.color.srcBlend),
                                       InitBlock.Enum32(desc.color.destBlend),
                                       InitBlock.Enum32(desc.color.op),
                                       InitBlock.Enum32(desc.alpha.srcBlend),
                                       InitBlock.Enum32(desc.alpha.destBlend),
                                       InitBlock.Enum32(desc.alpha.op),
                                       InitBlock.LiteralU32(desc.writeMask))).ToList();

            while (blendSpecVals.Count < 8) // \todo: get the limits from somwhere!!!
            {
                blendSpecVals.Add(
                    InitBlock.Struct(
                        "D3D11_RENDER_TARGET_BLEND_DESC",
                        InitBlock.LiteralBool(false),
                        InitBlock.Enum32("D3D11_BLEND", "D3D11_BLEND_ONE", D3D11_BLEND.D3D11_BLEND_ONE),
                        InitBlock.Enum32("D3D11_BLEND", "D3D11_BLEND_ZERO", D3D11_BLEND.D3D11_BLEND_ZERO),
                        InitBlock.Enum32("D3D11_BLEND_OP", "D3D11_BLEND_OP_ADD", D3D11_BLEND_OP.D3D11_BLEND_OP_ADD),
                        InitBlock.Enum32("D3D11_BLEND", "D3D11_BLEND_ONE", D3D11_BLEND.D3D11_BLEND_ONE),
                        InitBlock.Enum32("D3D11_BLEND", "D3D11_BLEND_ZERO", D3D11_BLEND.D3D11_BLEND_ZERO),
                        InitBlock.Enum32("D3D11_BLEND_OP", "D3D11_BLEND_OP_ADD", D3D11_BLEND_OP.D3D11_BLEND_OP_ADD),
                        InitBlock.LiteralU32((UInt32)D3D11_COLOR_WRITE_ENABLE.D3D11_COLOR_WRITE_ENABLE_ALL)));
            }

            var blendSpecsVal = InitBlock.Array(
                rtBlendDescType,
                blendSpecVals);


            InitBlock.AppendComment("D3D11 Output Merger");
            var blendDescVal =
                InitBlock.Temp("blendDesc",
                               InitBlock.Struct(
                                   "D3D11_BLEND_DESC",
                                   InitBlock.LiteralBool(false),
                                   InitBlock.LiteralBool(true),
                                   blendSpecsVal));

            InitBlock.SetArrow(
                CtorThis,
                blendStateField,
                EmitTarget.GetNullPointer(blendStateType));

            InitBlock.CallCOM(
                CtorDevice,
                "ID3D11Device",
                "CreateBlendState",
                blendDescVal.GetAddress(),
                InitBlock.GetArrow(CtorThis, blendStateField).GetAddress());

            DtorBlock.CallCOM(
                DtorBlock.GetArrow(DtorThis, blendStateField),
                "IUnknown",
                "Release");



            // Emit HLSL code for PS

            InitBlock.AppendComment("D3D11 Pixel Shader");

            hlslContext = new EmitContextHLSL(SharedHLSL, Range, this.EmitClass.GetName());

            var entryPointSpan = hlslContext.EntryPointSpan;

            entryPointSpan.WriteLine("void main(");

            bool firstParam = true;

            hlslContext.DeclareConnectorAndBind(
                rasterVertex,
                GetAttribute(fragmentElement, "__rv2f"),
                ref firstParam,
                entryPointSpan);

            hlslContext.DeclareParamAndBind(
                GetAttribute(fragmentElement, "PS_ScreenSpacePosition"),
                "SV_Position",
                ref firstParam,
                entryPointSpan);

            for (int ii = 0; ii < renderTargetCount; ++ii)
            {
                if (!firstParam)
                {
                    entryPointSpan.WriteLine(",");
                }
                firstParam = false;

                var    sourceInfo = _renderTargetSources[ii];
                MidExp exp        = null;
                if (sourceInfo.combinedExp != null)
                {
                    // \todo: Validate other bits and bobs!!!
                    exp = sourceInfo.combinedExp;
                }
                else
                {
                    throw new NotImplementedException();
                }

                entryPointSpan.Write("\tout {1} target{0} : SV_Target{0}", ii,
                                     hlslContext.EmitType(exp.Type));
            }
            entryPointSpan.WriteLine(" )");
            entryPointSpan.WriteLine("{");


            hlslContext.EmitTempRecordCtor(
                entryPointSpan,
                fragmentElement,
                GetAttribute(pixelElement, "__ps2om"));

            var psCullFragmentAttr = GetAttribute(fragmentElement, "PS_CullFragment");

            entryPointSpan.WriteLine("\tif( {0} ) discard;",
                                     hlslContext.EmitAttribRef(psCullFragmentAttr, entryPointSpan));


            for (int ii = 0; ii < renderTargetCount; ++ii)
            {
                var    sourceInfo = _renderTargetSources[ii];
                MidExp exp        = null;
                if (sourceInfo.combinedExp != null)
                {
                    // \todo: Validate other bits and bobs!!!
                    exp = sourceInfo.combinedExp;
                }
                else
                {
                    throw new NotImplementedException();
                }

                entryPointSpan.WriteLine("\ttarget{0} = {1};",
                                         ii,
                                         hlslContext.EmitExp(exp, entryPointSpan));
            }

            entryPointSpan.WriteLine("}");

            hlslContext.EmitConstantBufferDecl();

            //

            EmitShaderSetup(
                hlslContext,
                "ps_5_0",
                "Pixel",
                "PS");
        }