public static void ProcessVectorSwizzle(FrontEndTranslator frontEnd, INamedTypeSymbol typeSymbol, ISymbol memberSymbol, AttributeData attribute) { if (memberSymbol is IFieldSymbol fieldSymbol) { ShaderLibrary.InstrinsicDelegate getterResolver = (FrontEndTranslator translator, List <IShaderIR> arguments, FrontEndContext context) => { ResolveVectorSwizzleGetter(translator, context, attribute, fieldSymbol.Type, arguments); }; ShaderLibrary.InstrinsicSetterDelegate setterResolver = (FrontEndTranslator translator, IShaderIR selfInstance, IShaderIR rhsIR, FrontEndContext context) => { ResolveVectorSwizzleSetter(translator, context, attribute, fieldSymbol.Type, selfInstance, rhsIR); }; frontEnd.mCurrentLibrary.CreateIntrinsicFunction(new FunctionKey(memberSymbol), getterResolver); frontEnd.mCurrentLibrary.CreateIntrinsicSetterFunction(new FunctionKey(fieldSymbol), setterResolver); } if (memberSymbol is IPropertySymbol propertySymbol) { ShaderLibrary.InstrinsicDelegate getterResolver = (FrontEndTranslator translator, List <IShaderIR> arguments, FrontEndContext context) => { ResolveVectorSwizzleGetter(translator, context, attribute, propertySymbol.Type, arguments); }; ShaderLibrary.InstrinsicSetterDelegate setterResolver = (FrontEndTranslator translator, IShaderIR selfInstance, IShaderIR rhsIR, FrontEndContext context) => { ResolveVectorSwizzleSetter(translator, context, attribute, propertySymbol.Type, selfInstance, rhsIR); }; if (propertySymbol.GetMethod != null) { frontEnd.mCurrentLibrary.CreateIntrinsicFunction(new FunctionKey(propertySymbol.GetMethod), getterResolver); } if (propertySymbol.SetMethod != null) { frontEnd.mCurrentLibrary.CreateIntrinsicSetterFunction(new FunctionKey(propertySymbol.SetMethod), setterResolver); } } }
/// <summary> /// Creates a simple intrinsic function (one whos ops are just value types of the args one-for-one) callback for the given symbol information. /// </summary> static public void CreateSimpleIntrinsicFunction(FrontEndTranslator translator, FunctionKey functionKey, OpInstructionType opType, ShaderType returnType) { ShaderLibrary.InstrinsicDelegate callback = (FrontEndTranslator translator, List <IShaderIR> arguments, FrontEndContext context) => { SimpleValueTypeIntrinsic(translator, context, opType, returnType, arguments); }; translator.mCurrentLibrary.CreateIntrinsicFunction(functionKey, callback); }
static public void CreateCompositeConstructIntrinsic(FrontEndTranslator translator, INamedTypeSymbol typeSymbol, IMethodSymbol methodSymbol, AttributeData attribute) { var shaderReturnType = translator.FindType(new TypeKey(typeSymbol)); ShaderLibrary.InstrinsicDelegate callback = (FrontEndTranslator translator, List <IShaderIR> arguments, FrontEndContext context) => { ProcessCompositeConstructIntrinsic(translator, shaderReturnType, arguments, context); }; translator.mCurrentLibrary.CreateIntrinsicFunction(new FunctionKey(methodSymbol), callback); }
/// <summary> /// Creates a simple intrinsic type (one whos ops are just value types of the args one-for-one) callback for the given symbol information from the provided attribute. /// </summary> static public void CreateSimpleIntrinsicType(FrontEndTranslator translator, INamedTypeSymbol typeSymbol, IMethodSymbol methodSymbol, AttributeData attribute) { var opTypeStr = attribute.ConstructorArguments[0].Value.ToString(); var opType = (OpInstructionType)Enum.Parse(typeof(OpInstructionType), opTypeStr, true); var shaderReturnType = translator.FindType(new TypeKey(methodSymbol.ReturnType)); ShaderLibrary.InstrinsicDelegate callback = (FrontEndTranslator translator, List <IShaderIR> arguments, FrontEndContext context) => { SimpleValueTypeIntrinsic(translator, context, opType, shaderReturnType, arguments); }; translator.mCurrentLibrary.CreateIntrinsicFunction(new FunctionKey(methodSymbol), callback); }
public static void ProcessVectorDefaultConstructor(FrontEndTranslator translator, INamedTypeSymbol typeSymbol, ShaderType shaderType) { ShaderLibrary.InstrinsicDelegate defaultConstructorResolver = (FrontEndTranslator translator, List <IShaderIR> arguments, FrontEndContext context) => { ResolveVectorDefaultConstructor(translator, context, shaderType); }; foreach (var constructor in typeSymbol.Constructors) { if (constructor.Parameters.Length == 0 && constructor.IsImplicitlyDeclared) { translator.mCurrentLibrary.CreateIntrinsicFunction(new FunctionKey(constructor), defaultConstructorResolver); } } }
/// <summary> /// Processes a function to create a simple extension intrinsic (one whos ops are just value types of the args one-for-one) callback for the given symbol information from the provided attribute. /// </summary> static public void ProcessSimpleExtensionIntrinsic(FrontEndTranslator translator, INamedTypeSymbol typeSymbol, IMethodSymbol methodSymbol, AttributeData attribute) { var extensionName = attribute.ConstructorArguments[0].Value.ToString(); var opTypeStr = attribute.ConstructorArguments[1].Value.ToString(); // @JoshD: Hack that this is tied to GLSLstd450. This should ideally be extended to work on any extension library type var extOpType = (GLSLstd450)Enum.Parse(typeof(GLSLstd450), opTypeStr, true); var shaderReturnType = translator.FindType(new TypeKey(methodSymbol.ReturnType)); ShaderLibrary.InstrinsicDelegate callback = (FrontEndTranslator translator, List <IShaderIR> arguments, FrontEndContext context) => { ResolveSimpleExtensionIntrinsic(translator, context, extensionName, (int)extOpType, shaderReturnType, arguments); }; translator.mCurrentLibrary.CreateIntrinsicFunction(new FunctionKey(methodSymbol), callback); }
static public void CreateArraySetType(FrontEndTranslator translator, INamedTypeSymbol typeSymbol, IMethodSymbol methodSymbol, AttributeData attribute) { // Do an access chain to get the element and then store the value inside the pointer ShaderLibrary.InstrinsicDelegate callback = (FrontEndTranslator translator, List <IShaderIR> arguments, FrontEndContext context) => { var selfOp = arguments[0]; var indexOp = translator.GetOrGenerateValueTypeFromIR(context.mCurrentBlock, arguments[1]); var valueOp = translator.GetOrGenerateValueTypeFromIR(context.mCurrentBlock, arguments[2]); var pointerType = valueOp.mResultType.FindPointerType(StorageClass.Function); var accessChainOp = translator.CreateOp(context.mCurrentBlock, OpInstructionType.OpAccessChain, pointerType, new List <IShaderIR> { selfOp, indexOp }); translator.CreateStoreOp(context.mCurrentBlock, accessChainOp, valueOp); }; translator.mCurrentLibrary.CreateIntrinsicFunction(new FunctionKey(methodSymbol), callback); }
/// <summary> /// Creates an intrinsic to retrieve an element from an array. This unfortunately has to use OpAccessChain because the other /// instruction requires an integer literal, but OpAccessChain returns a pointer (which isn't exposed). This function will return the element as a value type. /// </summary> static public void CreateArrayGetType(FrontEndTranslator translator, INamedTypeSymbol typeSymbol, IMethodSymbol methodSymbol, AttributeData attribute) { var shaderReturnType = translator.FindType(new TypeKey(methodSymbol.ReturnType)); var pointerReturnType = shaderReturnType.FindPointerType(StorageClass.Function); ShaderLibrary.InstrinsicDelegate callback = (FrontEndTranslator translator, List <IShaderIR> arguments, FrontEndContext context) => { var selfOp = arguments[0]; var indexOp = translator.GetOrGenerateValueTypeFromIR(context.mCurrentBlock, arguments[1]); var accessChainOp = translator.CreateOp(context.mCurrentBlock, OpInstructionType.OpAccessChain, pointerReturnType, new List <IShaderIR> { selfOp, indexOp }); // Always convert the pointer to a value type var returnOp = translator.GetOrGenerateValueTypeFromIR(context.mCurrentBlock, accessChainOp); context.Push(returnOp); }; translator.mCurrentLibrary.CreateIntrinsicFunction(new FunctionKey(methodSymbol), callback); }
static public void CreateSampledImageIntrinsicFunction(FrontEndTranslator translator, INamedTypeSymbol typeSymbol, IMethodSymbol methodSymbol, AttributeData attribute) { var intrinsicData = ImageIntrinsicAttributeData.Parse(attribute); if (intrinsicData == null) { throw new Exception("Failed to parse attribute"); } var shaderReturnType = translator.FindType(new TypeKey(methodSymbol.ReturnType)); ShaderLibrary.InstrinsicDelegate callback = null; var param0Type = translator.FindType(new TypeKey(methodSymbol.Parameters[0].Type)); if (param0Type.mBaseType == OpType.SampledImage) { callback = (FrontEndTranslator translator, List <IShaderIR> arguments, FrontEndContext context) => { SampledImageValueTypeIntrinsic(translator, context, intrinsicData, shaderReturnType, arguments); }; } else if (param0Type.mBaseType == OpType.Image) { var param1Type = translator.FindType(new TypeKey(methodSymbol.Parameters[1].Type)); if (param1Type.mBaseType == OpType.Sampler) { callback = (FrontEndTranslator translator, List <IShaderIR> arguments, FrontEndContext context) => { SplitSampledImageValueTypeIntrinsic(translator, context, intrinsicData, shaderReturnType, arguments); }; } } if (callback == null) { throw new Exception("Failed to parse attribute"); } translator.mCurrentLibrary.CreateIntrinsicFunction(new FunctionKey(methodSymbol), callback); }