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