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 })); }); }
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); }
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); }
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); } }