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