public void DefaultConstructType(INamedTypeSymbol typeSymbol, ShaderOp variableOp) { var defaultConstructorSymbol = FindDefaultConstructorSymbol(typeSymbol); if (defaultConstructorSymbol == null) { return; } var constructorKey = new FunctionKey(defaultConstructorSymbol); // If this is an intrinsic (defined by the compiler and not user defined) then invoke it. var constructorIntrinsic = mFrontEnd.mCurrentLibrary.FindIntrinsicFunction(constructorKey); if (constructorIntrinsic != null) { constructorIntrinsic(mFrontEnd, new List <IShaderIR>(), mContext); mFrontEnd.CreateStoreOp(mContext.mCurrentBlock, variableOp, mContext.Pop()); return; } // Otherwise see if this is user defined var constructorFn = mFrontEnd.mCurrentLibrary.FindFunction(constructorKey); if (constructorFn != null) { mFrontEnd.GenerateFunctionCall(constructorFn, variableOp, null, mContext); return; } var derefType = variableOp.mResultType.GetDereferenceType(); var defaultValue = mFrontEnd.DefaultConstructPrimitive(derefType, mContext); mFrontEnd.CreateStoreOp(mContext.mCurrentBlock, variableOp, defaultValue); }
public static void CopyInterfaceFields(FrontEndTranslator translator, ShaderOp thisOp, ShaderInterfaceSet interfaceSet, InterfaceFieldCopyMode copyMode, FrontEndContext context) { foreach (var interfaceField in interfaceSet) { var interfaceInstance = interfaceSet.GetFieldInstance(translator, interfaceField, context); if (interfaceInstance == null) { continue; } var shaderFieldInstance = translator.GenerateAccessChain(thisOp, interfaceField.ShaderField.mMeta.mName, context); if (copyMode == InterfaceFieldCopyMode.Input) { translator.CreateStoreOp(context.mCurrentBlock, shaderFieldInstance, interfaceInstance); } else { translator.CreateStoreOp(context.mCurrentBlock, interfaceInstance, shaderFieldInstance); } } }
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); }
public static void CreateGlobalVariableInitializeFunction(FrontEndTranslator translator, ShaderType shaderType, ShaderEntryPointInfo entryPoint, EntryPointInterfaceInfo interfaceInfo, FrontEndContext context) { // First check if any global variables that need the variable initialization function exist. If not then don't emit anything. bool globalVariablesExist = false; foreach (var globalField in interfaceInfo.GlobalFields) { if (globalField.InitialValue != null) { globalVariablesExist = true; } } if (!globalVariablesExist) { return; } var library = translator.mCurrentLibrary; var voidType = library.FindType(new TypeKey(typeof(void))); var initGlobalFunction = translator.CreateFunctionAndType(shaderType, voidType, "InitGlobals", null, null); initGlobalFunction.mBlocks.Add(new ShaderBlock()); entryPoint.mGlobalsInitializationFunction = initGlobalFunction; // Add the store op for each global variable context.mCurrentFunction = initGlobalFunction; context.mCurrentBlock = initGlobalFunction.mBlocks[0]; foreach (var globalField in interfaceInfo.GlobalFields) { if (globalField.InitialValue != null) { translator.CreateStoreOp(context.mCurrentBlock, globalField.InstanceOp, globalField.InitialValue); } } translator.FixupBlockTerminators(context.mCurrentFunction); }
public static void ResolveVectorSwizzleSetter(FrontEndTranslator translator, FrontEndContext context, AttributeData attribute, ISymbol returnType, IShaderIR selfInstance, IShaderIR rhsIR) { var swizzleElements = attribute.ConstructorArguments[0].Values; var selfValue = translator.GetOrGenerateValueTypeFromIR(context.mCurrentBlock, selfInstance); var selfValueType = selfValue.mResultType.GetDereferenceType(); var componentCount = (UInt32)(selfValueType.mParameters[1] as ShaderConstantLiteral).mValue; var rhs = translator.GetOrGenerateValueTypeFromIR(context.mCurrentBlock, rhsIR); // If we're setting just a single element, then do an access chain and to set that element if (swizzleElements.Length == 1) { // Find what element we're setting var constantLiteral = translator.CreateConstantLiteral((UInt32)swizzleElements[0].Value); var memberIndexConstant = translator.CreateConstantOp(translator.FindType(typeof(uint)), constantLiteral); // Lookup the result type var resultType = translator.mCurrentLibrary.FindType(new TypeKey(returnType)); resultType = resultType.FindPointerType(selfValue.mResultType.mStorageClass); // Build the access chain to the element var memberVariableOp = translator.CreateOp(context.mCurrentBlock, OpInstructionType.OpAccessChain, resultType, new List <IShaderIR> { selfInstance, memberIndexConstant }); // Then set this back to the lhs side translator.CreateStoreOp(context.mCurrentBlock, memberVariableOp, rhs); } // Otherwise construct a new vector and set it over else { var swizzleArgs = new List <IShaderIR>() { selfValue, rhs }; // Build up a set of what element indices were in the swizzle var elementSet = new HashSet <UInt32>(); foreach (var element in swizzleElements) { elementSet.Add((UInt32)element.Value); } // Foreach element in the new vector, choose if we take it from the rhs or the lhs. If the element index is in the swizzle ops, // then take the next element from rhs, otherwise take the same index from lhs. var rhsElementIndex = 0u; for (uint element = 0; element < componentCount; ++element) { if (elementSet.Contains(element)) { swizzleArgs.Add(translator.CreateConstantLiteral(componentCount + rhsElementIndex)); ++rhsElementIndex; } else { swizzleArgs.Add(translator.CreateConstantLiteral(element)); } } // To build the setter, first create the new vector from components in the lhs/rhs as appropriate. var op = translator.CreateOp(context.mCurrentBlock, OpInstructionType.OpVectorShuffle, selfValueType, swizzleArgs); // Then set this back to the lhs side translator.CreateStoreOp(context.mCurrentBlock, selfInstance, op); } }