Example #1
0
 void IncDecOp(FrontEndTranslator translator, ShaderType resultType, string opToken, ShaderType operandType, OpInstructionType instructionType)
 {
     CreateUnaryOpIntrinsic(new UnaryOpKey(opToken, operandType), (IShaderIR operandIR, FrontEndContext context) =>
     {
         var operandValueOp      = translator.GetOrGenerateValueTypeFromIR(context.mCurrentBlock, operandIR);
         IShaderIR oneConstantOp = null;
         if (resultType.mBaseType == OpType.Int)
         {
             oneConstantOp = translator.CreateConstantOp(operandType, 1);
         }
         else if (resultType.mBaseType == OpType.Float)
         {
             oneConstantOp = translator.CreateConstantOp(operandType, 1.0f);
         }
         return(translator.CreateOp(context.mCurrentBlock, instructionType, resultType, new List <IShaderIR> {
             operandValueOp, oneConstantOp
         }));
     });
 }
Example #2
0
        public static ShaderType ProcessFixedArrayType(FrontEndTranslator translator, INamedTypeSymbol typeSymbol, AttributeData attribute)
        {
            var componentType  = translator.FindType(new TypeKey(attribute.ConstructorArguments[0].Value as ISymbol));
            var componentCount = (UInt32)attribute.ConstructorArguments[1].Value;

            var shaderType = translator.CreateType(typeSymbol, OpType.Array);

            shaderType.mParameters.Add(componentType);
            shaderType.mParameters.Add(translator.CreateConstantOp(componentCount));

            ProcessVectorDefaultConstructor(translator, typeSymbol, shaderType);

            return(shaderType);
        }
Example #3
0
        public static void ResolveVectorDefaultConstructor(FrontEndTranslator translator, FrontEndContext context, ShaderType vectorType)
        {
            var componentType  = vectorType.mParameters[0] as ShaderType;
            var componentCount = (UInt32)(vectorType.mParameters[1] as ShaderConstantLiteral).mValue;

            var zeroConstantLiteral = translator.CreateConstantLiteralZero(componentType);
            var zeroConstant        = translator.CreateConstantOp(componentType, zeroConstantLiteral);

            var constructorArgs = new List <IShaderIR>();

            for (var i = 0; i < componentCount; ++i)
            {
                constructorArgs.Add(zeroConstant);
            }
            var op = translator.CreateOp(context.mCurrentBlock, OpInstructionType.OpCompositeConstruct, vectorType, constructorArgs);

            context.Push(op);
        }
Example #4
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);
            }
        }