public ShaderOp CastUIntToInt(ShaderType resultType, IShaderIR expressionOp, FrontEndContext context) { return(SimpleCast(resultType, OpInstructionType.OpBitcast, expressionOp, context)); }
static void SplitSampledImageValueTypeIntrinsic(FrontEndTranslator translator, FrontEndContext context, ImageIntrinsicAttributeData intrinsicData, ShaderType returnType, List <IShaderIR> arguments) { var valueOps = new List <IShaderIR>(); var imageParam = translator.GetOrGenerateValueTypeFromIR(context.mCurrentBlock, arguments[0]); var samplerParam = translator.GetOrGenerateValueTypeFromIR(context.mCurrentBlock, arguments[1]); // Try and generate a sampled image type for this image. If we do create a new type that wasn't necessary that's fine because it'll be de-duped in the binary backend. var sampledImageTypeStr = new TypeName { Name = "GeneratedSampledImage_" + imageParam.mResultType.ToString() }; var sampledImageType = translator.FindType(new TypeKey(sampledImageTypeStr)); if (sampledImageType == null) { sampledImageType = translator.CreateType(new TypeKey(sampledImageTypeStr), sampledImageTypeStr, OpType.SampledImage, null); sampledImageType.mParameters.Add(imageParam.mResultType.GetDereferenceType()); } // Combine the image and sampler together into a sampled image. This is a bit annoying, but a sampled image // can't be stored into a variable so this has to be a temporary. Use this combined sampled image in place of the first two args to the intrinsics. var sampledImageOp = translator.CreateOp(context.mCurrentBlock, OpInstructionType.OpSampledImage, sampledImageType, new List <IShaderIR>() { imageParam, samplerParam }); valueOps.Add(sampledImageOp); WriteArguments(translator, context, valueOps, intrinsicData, arguments, 2); var op = translator.CreateOp(context.mCurrentBlock, intrinsicData.OpType, returnType, valueOps); context.Push(op); }
public static ShaderFunction GenerateFunction_ShaderTypeParam(FrontEndTranslator translator, ShaderType shaderType, string functionName, out ShaderOp thisOp) { var library = translator.mCurrentLibrary; var voidType = library.FindType(new TypeKey(typeof(void))); var thisType = shaderType.FindPointerType(StorageClass.Function); var fnArgsTypes = new List <ShaderType>() { thisType }; var function = translator.CreateFunctionAndType(shaderType, voidType, functionName, null, fnArgsTypes); thisOp = translator.CreateOp(function.mParametersBlock, OpInstructionType.OpFunctionParameter, thisType, null); thisOp.DebugInfo.Name = "self"; function.mBlocks.Add(new ShaderBlock()); return(function); }
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); } } }
public override void Visit(ShaderType shaderType) { GetId(shaderType); base.Visit(shaderType); }
void AddSimpleValueTypeUnaryOp(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); return(translator.CreateOp(context.mCurrentBlock, instructionType, resultType, new List <IShaderIR> { operandValueOp })); }); }
void LogicOrAndOp(FrontEndTranslator translator, ShaderType resultType, ShaderType lhsType, string opToken, ShaderType rhsType, OpInstructionType instructionType, bool isOr) { CreateComplexBinaryOpIntrinsic(new BinaryOpKey(lhsType, opToken, rhsType), (SyntaxNode lhsExpression, SyntaxNode rhsExpression, FrontEndContext context) => { LogicalOrAnd(lhsExpression, rhsExpression, context, isOr); return(context.Pop() as ShaderOp); }); }
public ConstantOpKey(ShaderType shaderType, object value) { mType = shaderType; mValue = value; Validate(); }
public ConstantOpKey(ShaderConstantLiteral constant) { mType = constant.mType; mValue = constant.mValue; Validate(); }
//---------------------------------------------------------------Casting public void AddCastIntrinsics(ShaderType castToType, ShaderType castFromType, CastDelegate castDelegate) { var tuple = new Tuple <ShaderType, ShaderType>(castToType, castFromType); CastIntrinsics.Add(tuple, castDelegate); }
//---------------------------------------------------------------Types public bool AddType(TypeKey key, ShaderType shaderType) { return(mTypeMap.TryAdd(key, shaderType)); }
static void CombinedSampledImageValueTypeIntrinsic(FrontEndTranslator translator, FrontEndContext context, ImageIntrinsicAttributeData intrinsicData, ShaderType returnType, List <IShaderIR> arguments) { var valueOps = new List <IShaderIR>(); var sampledImageParam = translator.GetOrGenerateValueTypeFromIR(context.mCurrentBlock, arguments[0]); var sampledImageType = sampledImageParam.mResultType; var imageType = sampledImageType.mParameters[0] as ShaderType; // Pull the image out of the sampled image. var imageOp = translator.CreateOp(context.mCurrentBlock, OpInstructionType.OpImage, imageType, new List <IShaderIR>() { sampledImageParam }); valueOps.Add(imageOp); WriteArguments(translator, context, valueOps, intrinsicData, arguments, 1); var op = translator.CreateOp(context.mCurrentBlock, intrinsicData.OpType, returnType, valueOps); context.Push(op); }
public ShaderOp CastFloatToUInt(ShaderType resultType, IShaderIR expressionOp, FrontEndContext context) { return(SimpleCast(resultType, OpInstructionType.OpConvertFToU, expressionOp, context)); }
public ShaderOp CastFloatToBool(ShaderType resultType, IShaderIR expressionOp, FrontEndContext context) { var constantOp = CreateConstantOp <float>(0.0f); return(SimpleCompareCast(resultType, OpInstructionType.OpFOrdNotEqual, expressionOp, constantOp, context)); }
public void CreateDummyEntryPoint(TypeDependencyCollector typeCollector, ShaderLibrary library, FrontEndTranslator frontEnd, ShaderType shaderType) { var context = new FrontEndContext(); context.mCurrentType = shaderType; if (shaderType.mEntryPoints.Count != 0) { return; } ShaderEntryPointInfo entryPoint = null; if (shaderType.mFragmentType == FragmentType.Pixel || shaderType.mFragmentType == FragmentType.None) { entryPoint = EntryPointGeneration.GeneratePixel(frontEnd, shaderType, null); } else if (shaderType.mFragmentType == FragmentType.Vertex) { entryPoint = EntryPointGeneration.GenerateVertex(frontEnd, shaderType, null); } typeCollector.Visit(entryPoint); }
public TypeKey(ShaderType shaderType) { mKey = shaderType.mMeta.mName; }
/// <summary> /// Does a simple extension intrinsic (one where all ops are value types). /// </summary> static void ResolveSimpleExtensionIntrinsic(FrontEndTranslator translator, FrontEndContext context, string extensionName, int extOpType, ShaderType returnType, List <IShaderIR> arguments) { var extensionImportOp = translator.mCurrentLibrary.GetOrCreateExtensionLibraryImport(extensionName); var extOpTypeOp = translator.CreateConstantLiteral(extOpType); var valueOps = new List <IShaderIR>(); valueOps.Add(extensionImportOp); valueOps.Add(extOpTypeOp); foreach (var argument in arguments) { valueOps.Add(translator.GetOrGenerateValueTypeFromIR(context.mCurrentBlock, argument)); } var op = translator.CreateOp(context.mCurrentBlock, OpInstructionType.OpExtInst, returnType, valueOps); context.Push(op); }
public UnaryOpKey(string opToken, ShaderType operandType) { OpToken = opToken; OperandType = operandType; }
void AddSimpleValueTypeBinaryOp(FrontEndTranslator translator, ShaderType resultType, ShaderType lhsType, string opToken, ShaderType rhsType, OpInstructionType instructionType) { CreateBinaryOpIntrinsic(new BinaryOpKey(lhsType, opToken, rhsType), (IShaderIR lhsExpression, IShaderIR rhsExpression, FrontEndContext context) => { var lhsValueOp = translator.GetOrGenerateValueTypeFromIR(context.mCurrentBlock, lhsExpression); var rhsValueOp = translator.GetOrGenerateValueTypeFromIR(context.mCurrentBlock, rhsExpression); return(translator.CreateOp(context.mCurrentBlock, instructionType, resultType, new List <IShaderIR> { lhsValueOp, rhsValueOp })); }); }
public BinaryOpKey(ShaderType leftType, string opToken, ShaderType rightType) { LeftType = leftType; OpToken = opToken; RightType = rightType; }
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 })); }); }
void WriteTypeDeclaration(ShaderType type, HashSet <UInt32> visitedTypeIds) { // Handle types existing more than once (for primitive deduping) var id = GetId(type); if (visitedTypeIds.Contains(id)) { return; } visitedTypeIds.Add(id); if (type.mBaseType == OpType.Void) { mWriter.WriteInstruction(2, Spv.Op.OpTypeVoid, GetId(type)); } else if (type.mBaseType == OpType.Bool) { mWriter.WriteInstruction(2, Spv.Op.OpTypeBool, GetId(type)); } else if (type.mBaseType == OpType.Int) { mWriter.WriteInstruction(4, Spv.Op.OpTypeInt, GetId(type)); WriteArgs(type.mParameters); } else if (type.mBaseType == OpType.Float) { mWriter.WriteInstruction(3, Spv.Op.OpTypeFloat, GetId(type)); WriteArgs(type.mParameters); } else if (type.mBaseType == OpType.Vector) { mWriter.WriteInstruction(4, Spv.Op.OpTypeVector, GetId(type)); WriteArgs(type.mParameters); } else if (type.mBaseType == OpType.Matrix) { mWriter.WriteInstruction(4, Spv.Op.OpTypeMatrix, GetId(type)); WriteArgs(type.mParameters); } else if (type.mBaseType == OpType.Pointer) { var dereferenceType = type.GetDereferenceType(); if (dereferenceType.mBaseType != OpType.Function) { var storageClass = ConvertStorageClass(type.mStorageClass); mWriter.WriteInstruction(4, Spv.Op.OpTypePointer, GetId(type), (UInt32)storageClass, GetId(dereferenceType)); } } else if (type.mBaseType == OpType.Array) { mWriter.WriteInstruction(4, Spv.Op.OpTypeArray, GetId(type)); WriteArgs(type.mParameters); } else if (type.mBaseType == OpType.Struct) { UInt16 instructionSize = (UInt16)(2 + type.mFields.Count); mWriter.WriteInstruction(instructionSize, Spv.Op.OpTypeStruct, GetId(type)); foreach (var field in type.mFields) { mWriter.Write(GetId(field.mType)); } } else if (type.mBaseType == OpType.Sampler) { UInt16 instructionSize = (UInt16)2; mWriter.WriteInstruction(instructionSize, Spv.Op.OpTypeSampler, GetId(type)); } else if (type.mBaseType == OpType.Image) { UInt16 instructionSize = (UInt16)9; mWriter.WriteInstruction(instructionSize, Spv.Op.OpTypeImage, GetId(type)); WriteArgs(type.mParameters); } else if (type.mBaseType == OpType.SampledImage) { UInt16 instructionSize = (UInt16)3; mWriter.WriteInstruction(instructionSize, Spv.Op.OpTypeSampledImage, GetId(type)); WriteArgs(type.mParameters); } else if (type.mBaseType == OpType.Function) { var instructionSize = 2 + type.mParameters.Count; mWriter.WriteInstruction((UInt16)(instructionSize), Spv.Op.OpTypeFunction, GetId(type)); WriteArgs(type.mParameters); } else { throw new Exception(); } }
public static void ResolveVectorDefaultConstructor(FrontEndTranslator translator, FrontEndContext context, ShaderType vectorType) { var componentType = vectorType.mParameters[0] as ShaderType; var componentOp = vectorType.mParameters[1] as ShaderOp; var componentCount = (UInt32)(componentOp.mParameters[0] 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 EntryPointFunction GenerateSpirVEntryPointFunction(FrontEndTranslator translator, ShaderType shaderType, string entryPointFnName) { EntryPointFunction entryPointFunction = new EntryPointFunction(); var library = translator.mCurrentLibrary; var voidType = library.FindType(new TypeKey(typeof(void))); entryPointFunction.ShaderFunction = translator.CreateFunctionAndType(shaderType, voidType, entryPointFnName, null, null); entryPointFunction.ShaderFunction.mBlocks.Add(new ShaderBlock()); entryPointFunction.Context = new FrontEndContext(); entryPointFunction.Context.mCurrentType = shaderType; entryPointFunction.Context.mCurrentFunction = entryPointFunction.ShaderFunction; entryPointFunction.Context.mCurrentBlock = entryPointFunction.ShaderFunction.mBlocks[0]; return(entryPointFunction); }
static void SampledImageValueTypeIntrinsic(FrontEndTranslator translator, FrontEndContext context, ImageIntrinsicAttributeData intrinsicData, ShaderType returnType, List <IShaderIR> arguments) { var valueOps = new List <IShaderIR>(); WriteArguments(translator, context, valueOps, intrinsicData, arguments, 0); var op = translator.CreateOp(context.mCurrentBlock, intrinsicData.OpType, returnType, valueOps); context.Push(op); }
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 string GenerateEntryPointFunctionName(FrontEndTranslator translator, ShaderType shaderType, ShaderFunction shaderFunction) { if (shaderFunction == null) { return("EntryPoint"); } return(shaderFunction.mMeta.mName + "_EntryPoint"); }
public static ShaderEntryPointInfo GeneratePixel(FrontEndTranslator translator, ShaderType shaderType, ShaderFunction function) { var entryPoint = new ShaderEntryPointInfo(); var context = new FrontEndContext(); context.mCurrentType = shaderType; var interfaceInfo = new EntryPointInterfaceInfo(); EntryPointGenerationShared.CollectInterface(translator, shaderType, interfaceInfo); // Build inputs block EntryPointGenerationShared.GenerateHardwareBuiltIns(translator, interfaceInfo.HardwareBuiltInInputs, StorageClass.Input, entryPoint.mInterfaceVariables, entryPoint.mDecorations); InputDeclarations.GenerateInputStruct(translator, shaderType, interfaceInfo.StageInputs, entryPoint.mInterfaceVariables, entryPoint.mDecorations); EntryPointGenerationShared.GenerateHardwareBuiltIns(translator, interfaceInfo.HardwareBuiltInOutputs, StorageClass.Output, entryPoint.mInterfaceVariables, entryPoint.mDecorations); OutputDeclarations.GenerateOutputFields(translator, shaderType, interfaceInfo.StageOutputs, entryPoint.mInterfaceVariables, entryPoint.mDecorations); UniformDeclarations.DeclareUniformBuffers(translator, interfaceInfo.UniformBuffers, entryPoint.mInterfaceVariables, entryPoint.mDecorations); UniformDeclarations.DeclareUniformConstants(translator, interfaceInfo.ConstantUniforms, entryPoint.mDecorations); // Create the functions required to run an entry point string entryPointName = EntryPointGenerationShared.GenerateEntryPointFunctionName(translator, shaderType, function); CreateGlobalVariableInitializeFunction(translator, shaderType, entryPoint, interfaceInfo, context); InputDeclarations.GenerateCopyInputsFunction(translator, shaderType, entryPoint, interfaceInfo); OutputDeclarations.GenerateCopyOutputsFunction(translator, shaderType, entryPoint, interfaceInfo); var entryPointFunction = GenerateSpirVEntryPointFunction(translator, shaderType, entryPointName); // Generate the entry point function body translator.TryGenerateFunctionCall(entryPoint.mGlobalsInitializationFunction, null, null, entryPointFunction.Context); EntryPointGenerationShared.ConstructShaderType(translator, shaderType, entryPointFunction.Context); var entryPointThisOp = entryPointFunction.Context.mThisOp; translator.TryGenerateFunctionCall(interfaceInfo.CopyInputsFunction.ShaderFunction, entryPointThisOp, null, entryPointFunction.Context); translator.TryGenerateFunctionCall(function, entryPointThisOp, null, entryPointFunction.Context); translator.TryGenerateFunctionCall(interfaceInfo.CopyOutputsFunction.ShaderFunction, entryPointThisOp, null, entryPointFunction.Context); translator.FixupBlockTerminators(entryPointFunction.ShaderFunction); // Make sure all global variables are added to the interface of the entry point AddGlobalVariables(translator, entryPoint, interfaceInfo); entryPoint.mEntryPointFunction = entryPointFunction.ShaderFunction; entryPoint.mStageType = shaderType.mFragmentType; shaderType.mEntryPoints.Add(entryPoint); EntryPointGenerationShared.AddExecutionMode(translator, entryPoint, entryPoint.mEntryPointFunction, Spv.ExecutionMode.ExecutionModeOriginUpperLeft); return(entryPoint); }
public static EntryPointFunction GenerateEntryPointCopyFunction(FrontEndTranslator translator, ShaderType shaderType, string functionName) { ShaderOp thisOp = null; var shaderFunction = GenerateFunction_ShaderTypeParam(translator, shaderType, functionName, out thisOp); var context = new FrontEndContext(); context.mCurrentBlock = shaderFunction.mBlocks[0]; context.mCurrentFunction = shaderFunction; var entryPointFunction = new EntryPointFunction(); entryPointFunction.Context = context; entryPointFunction.ShaderFunction = shaderFunction; entryPointFunction.ShaderTypeInstanceOp = thisOp; return(entryPointFunction); }
public ShaderOp CastUnsignedConvert(ShaderType resultType, IShaderIR expressionOp, FrontEndContext context) { return(SimpleCast(resultType, OpInstructionType.OpUConvert, expressionOp, context)); }