// 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"); }