protected MidAttributeWrapperDecl GetAttribute(MidElementDecl element, string name) { var result = FindAttribute(element, name); if (result != null) { return(result); } throw new NotImplementedException(); }
protected MidAttributeWrapperDecl FindAttribute(MidElementDecl element, string name) { foreach (var a in element.AttributeWrappers) { if (a.Name == Identifiers.simpleIdentifier(name)) { return(a); } } return(null); }
public override void EmitImplSetup() { constantElement = GetElement("Constant"); InitBlock.AppendComment("D3D11 Geometry Shader"); var gsEnabledAttr = FindAttribute(constantElement, "__D3D11GeometryShaderEnabled"); if (gsEnabledAttr == null) { return; } var uniformElement = GetElement("Uniform"); var fineVertexElement = GetElement("FineVertex"); var rasterVertexElement = GetElement("RasterVertex"); var geometryInputElement = GetElement("GeometryInput"); var geometryOutputElement = GetElement("GeometryOutput"); hlslContext = new EmitContextHLSL(SharedHLSL, Range, this.EmitClass.GetName()); var entryPointSpan = hlslContext.EntryPointSpan; var gsInstanceCount = GetAttribute(constantElement, "GS_InstanceCount"); var gsInputVertexCount = GetAttribute(constantElement, "GS_InputVertexCount"); var gsMaxOutputVertexCount = GetAttribute(constantElement, "GS_MaxOutputVertexCount"); var gsInstanceID = GetAttribute(geometryInputElement, "GS_InstanceID"); var gsInputVertices = GetAttribute(geometryInputElement, "GS_InputVertices"); var gsOutputStream = GetAttribute(geometryOutputElement, "GS_OutputStream"); hlslContext.GenerateConnectorType(fineVertexElement); hlslContext.GenerateConnectorType(rasterVertexElement); entryPointSpan.WriteLine("[instance({0})]", hlslContext.EmitAttrLit(gsInstanceCount)); entryPointSpan.WriteLine("[maxvertexcount({0})]", hlslContext.EmitAttrLit(gsMaxOutputVertexCount)); entryPointSpan.WriteLine("void main("); bool first = true; // \todo: "triangle" or appropriate prefix... hlslContext.DeclareParamAndBind( gsInputVertices, hlslContext.MakeArrayType( hlslContext.GenerateConnectorType(fineVertexElement), hlslContext.EmitAttribRef(gsInputVertexCount, null)), null, ref first, entryPointSpan, prefix: "triangle "); hlslContext.DeclareParamAndBind( gsOutputStream, null, ref first, entryPointSpan, prefix: "inout "); hlslContext.DeclareParamAndBind( gsInstanceID, "SV_GSInstanceID", ref first, entryPointSpan); entryPointSpan.WriteLine("\t)"); entryPointSpan.WriteLine("{"); var gi2go = hlslContext.EmitTempRecordCtor( entryPointSpan, geometryInputElement, GetAttribute(geometryOutputElement, "__gi2go")); hlslContext.BindAttr( GetAttribute(rasterVertexElement, "__gi2rv"), gi2go); var output = hlslContext.EmitConnectorCtor( entryPointSpan, geometryOutputElement); entryPointSpan.WriteLine("}"); hlslContext.EmitConstantBufferDecl(); EmitShaderSetup( hlslContext, "gs_5_0", "Geometry", "GS"); }
public override void EmitImplSetup() { constantElement = GetElement("Constant"); var uniformElement = GetElement("Uniform"); var fineVertexElement = GetElement("FineVertex"); var rasterVertexElement = GetElement("RasterVertex"); InitBlock.AppendComment("D3D11 Domain Shader"); var tessEnabledAttr = FindAttribute(constantElement, "__D3D11TessellationEnabled"); if (tessEnabledAttr == null) { return; } var outputPatchElement = GetElement("OutputPatch"); var controlPointElement = GetElement("ControlPoint"); // \todo: Need to check whether GS is enabled. var gsEnabledAttr = FindAttribute(constantElement, "__D3D11GeometryShaderEnabled"); var outputElement = fineVertexElement; if (gsEnabledAttr == null) { outputElement = rasterVertexElement; } hlslContext = new EmitContextHLSL(SharedHLSL, Range, this.EmitClass.GetName()); var entryPointSpan = hlslContext.EntryPointSpan; var outputControlPointCount = GetAttribute(constantElement, "HS_OutputControlPointCount"); var tsDomain = GetAttribute(constantElement, "TS_Domain"); // Bind a bunch of attributes that really represent constants: hlslContext.BindAttrLit( GetAttribute(constantElement, "TriangleDomain"), "tri"); hlslContext.BindAttrLit( GetAttribute(constantElement, "QuadDomain"), "quad"); hlslContext.BindAttrLit( GetAttribute(constantElement, "FractionalOddPartitioning"), "fractional_odd"); hlslContext.BindAttrLit( GetAttribute(constantElement, "IntegerPartitioning"), "integer"); hlslContext.BindAttrLit( GetAttribute(constantElement, "TriangleCWTopology"), "triangle_cw"); hlslContext.GenerateConnectorType(controlPointElement); hlslContext.GenerateConnectorType(outputElement); entryPointSpan.WriteLine("[domain(\"{0}\")]", hlslContext.EmitAttrLit(tsDomain)); entryPointSpan.WriteLine("{0} main(", hlslContext.GenerateConnectorType(outputElement)); bool first = true; if (outputPatchElement.Attributes.Any((a) => a.IsOutput)) { hlslContext.DeclareConnectorAndBind( outputPatchElement, GetAttribute(fineVertexElement, "__op2dv"), ref first, entryPointSpan); } // \todo: These should not be required, but seem related // to an fxc bug where it expects the tess-factor inputs // to be re-declared in the DS... var edgeFactors = GetAttribute(outputPatchElement, "HS_EdgeFactors"); var insideFactors = GetAttribute(outputPatchElement, "HS_InsideFactors"); /* * hlslContext.DeclareParamAndBind( * edgeFactors, * "SV_TessFactor", * ref first, * entryPointSpan); * * hlslContext.DeclareParamAndBind( * insideFactors, * "SV_InsideTessFactor", * ref first, * entryPointSpan); */ hlslContext.DeclareParamAndBind( GetAttribute(fineVertexElement, "DS_DomainLocation"), "SV_DomainLocation", ref first, entryPointSpan); hlslContext.DeclareParamAndBind( GetAttribute(fineVertexElement, "DS_InputControlPoints"), null, ref first, entryPointSpan); /* * * entryPointSpan.WriteLine(","); * entryPointSpan.WriteLine("\tconst OutputPatch<{0}, {1}> DS_InputControlPoints", * hlslContext.GenerateConnectorType(outputControlPointElement), * hlslContext.EmitAttribRef( * outputControlPointCount, * null)); */ entryPointSpan.WriteLine("\t)"); entryPointSpan.WriteLine("{"); if (fineVertexElement != outputElement) { hlslContext.EmitTempRecordCtor( entryPointSpan, fineVertexElement, GetAttribute(rasterVertexElement, "__f2rhelper")); } var output = hlslContext.EmitConnectorCtor( entryPointSpan, outputElement); entryPointSpan.WriteLine("\treturn {0};", output); entryPointSpan.WriteLine("}"); hlslContext.EmitConstantBufferDecl(); EmitShaderSetup( hlslContext, "ds_5_0", "Domain", "DS"); }
private ShaderFacetInfo CreateDirectFacet( MidFacetDecl midFacet, MidElementDecl constantElement, MidElementDecl uniformElement, IEmitClass ifaceClass, EmitEnv env) { var midAttributes = midFacet.Attributes.ToArray(); var attributeCount = midAttributes.Length; var attributeInfos = new ShaderAttributeInfo[attributeCount]; var result = new ShaderFacetInfo { OriginalClass = midFacet.OriginalShaderClass.Decl, FacetAccessor = (b, shaderObj) => shaderObj, Attributes = attributeInfos }; for (int ii = 0; ii < attributeCount; ++ii) { var midAttribute = midAttributes[ii]; var midElement = midAttribute.Element; if (midAttribute.IsAbstract) { continue; } if (midElement == constantElement) { if (midAttribute.Exp == null) { continue; } env.Insert(midAttribute, (b) => EmitExp(midAttribute.Exp, b, env)); } else if (midElement == uniformElement) { if (midAttribute.Exp != null) { continue; } if (!midAttribute.IsInput) { continue; } var attrType = EmitType(midAttribute.Type, env); var attrName = midAttribute.Name.ToString(); ifaceClass.WrapperWriteLine(""); ifaceClass.WrapperWriteLine( "// input @Uniform {0} {1}", midAttribute.Type, attrName); var attrField = ifaceClass.AddFieldAndAccessors( attrType, attrName); var attrInfo = new ShaderAttributeInfo(); attrInfo.AttributeDecl = midAttribute; attrInfo.Accessor = (b, shaderObj) => b.GetArrow( shaderObj, attrField); attrInfo.Type = attrType; attrInfo.Name = attrName; attributeInfos[ii] = attrInfo; } } return(result); }