Example #1
0
        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);
        }
Example #2
0
        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);
                }
            }
        }
Example #3
0
 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);
 }
Example #4
0
        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);
        }
Example #5
0
        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);
            }
        }